1. 整合的目标
- 使Spring中的IOC容器来管理Hibernate中的SessionFactory,使得在编写dao类时不需要每次手动创建SessionFactory。
- 使Hibernate使用上Spring的声明式事务,使得在编写dao类时不用再执行commit、close等操作,事务管理器在commit()之后会自动关闭事务。
2. 整合步骤
要求:利用Spring和Hibernate实现Person类的增删改查且查询House类(和Person类有多对一关系)
-
前期准备
在数据库中创建一个名为s_h的数据库 -
项目目录结构
项目结构 -
全部jar包
jar包
-
创建一个module
创建module -
正常引入Hibernate的jar包
-
创建hibernate.cfg.xml配置文件
<?xml version="1.0" encoding="utf-8"?>
<!-- 指定Hibernate配置文件的DTD信息 -->
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!-- hibernate- configuration是连接配置文件的根元素 -->
<hibernate-configuration>
<session-factory>
<!-- 配置Hibernate基本属性 -->
<!-- 1.数据源需配置到IOC容器中,则在此处不用再配置数据源 -->
<!-- 2.关联的hbm.xml映射文件也在IOC容器配置SessionFactory实例时再进行配置 -->
<!-- 3.配置Hibernate基本属性:方言,SQL显示及格式化,生成数据表的策略,二级缓存等 -->
<!-- 指定数据库方言 -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- 根据需要自动创建数据表 -->
<property name="hbm2ddl.auto">update</property>
<!-- 显示Hibernate持久化操作所生成的SQL -->
<property name="show_sql">true</property>
<!-- 将SQL脚本进行格式化后再输出 -->
<property name="hibernate.format_sql">true</property>
</session-factory>
</hibernate-configuration>
- 创建持久化类pers.domain.Person.java和pers.domian.House.java
package pers.domain;
public class Person {
private int personId;
private String realName;
private String telephone;
private String address;
public int getPersonId() {
return personId;
}
public void setPersonId(int personId) {
this.personId = personId;
}
public String getRealName() {
return realName;
}
public void setRealName(String realName) {
this.realName = realName;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Person{" +
"personId=" + personId +
", realName='" + realName + '\'' +
", telephone='" + telephone + '\'' +
", address='" + address + '\'' +
'}';
}
}
package pers.domain;
public class House {
private int houseId;
private String houseName;
private float houseArea;
private String apartmentLayout;
private Person person;
public int getHouseId() {
return houseId;
}
public void setHouseId(int houseId) {
this.houseId = houseId;
}
public String getHouseName() {
return houseName;
}
public void setHouseName(String houseName) {
this.houseName = houseName;
}
public float getHouseArea() {
return houseArea;
}
public void setHouseArea(float houseArea) {
this.houseArea = houseArea;
}
public String getApartmentLayout() {
return apartmentLayout;
}
public void setApartmentLayout(String apartmentLayout) {
this.apartmentLayout = apartmentLayout;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
@Override
public String toString() {
return "House{" +
"houseId=" + houseId +
", houseName='" + houseName + '\'' +
", houseArea=" + houseArea +
", apartmentLayout='" + apartmentLayout + '\'' +
", person=" + person +
'}';
}
}
- 创建持久化类及对应的Person.hbm.xml和House.hbm.xml映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="pers.domain.Person" table="tab_person" lazy="false">
<id name="personId" type="java.lang.Integer">
<column name="person_id" />
<generator class="native" />
</id>
<property name="realName" type="java.lang.String">
<column name="real_name" />
</property>
<property name="telephone" type="java.lang.String">
<column name="telephone" />
</property>
<property name="address" type="java.lang.String">
<column name="address" />
</property>
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="pers.domain.House" table="tab_house" lazy="false">
<id name="houseId" type="java.lang.Integer">
<column name="house_id" />
<generator class="native" />
</id>
<property name="houseName" type="java.lang.String">
<column name="house_name" />
</property>
<property name="houseArea" type="java.lang.Float">
<column name="house_area" />
</property>
<property name="apartmentLayout" type="java.lang.String">
<column name="apartment_layout" />
</property>
<!-- 单向多对一 name为House的属性名 class为对应的Person类名 column为House的外键-->
<many-to-one name="person" class="pers.domain.Person" column="person_id" />
</class>
</hibernate-mapping>
- 正常引入Spring的jar包
- 创建db.properties
jdbc.user=root
jdbc.password=123456
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/s_h?useUnicode=true&characterEncoding=utf8
jdbc.initPoolSize=5
jdbc.maxPoolSize=10
- 创建applicationContext.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 配置注解扫描包 -->
<context:component-scan base-package="pers" />
<!-- 配置数据源 -->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
<property name="driverClass" value="${jdbc.driverClass}" />
<property name="jdbcUrl" value="${jdbc.jdbcUrl}" />
<property name="initialPoolSize" value="${jdbc.initPoolSize}" />
<property name="maxPoolSize" value="${jdbc.maxPoolSize}" />
</bean>
<!-- 配置Hibernate的SessionFactory实例,通过Spring提供的LocalSessionFactoryBean进行配置 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
<property name="mappingLocations" value="classpath:pers/domain/*.hbm.xml" />
</bean>
<!-- 配置Spring的声明式事务 -->
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 配置事务属性 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="*"/>
</tx:attributes>
</tx:advice>
<!--配置切点,并将切点与事务联系起来 -->
<aop:config>
<aop:pointcut expression="execution(* pers.service.*.*(..))" id="txPointCut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
</aop:config>
</beans>
- 创建pers.test.SpringHibernateTest.java测试数据源,此时数据库会生成两张表
package pers.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pers.domain.House;
import pers.domain.Person;
import pers.service.HouseService;
import pers.service.PersonService;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.List;
public class SpringHibernateTest {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
@Test
public void testDataSource() throws SQLException {
DataSource dataSource = ctx.getBean(DataSource.class);
System.out.println(dataSource.getConnection());
}
}
- 创建pers.service.PersonService和pers.service.HouseService
package pers.service;
import org.springframework.stereotype.Service;
import pers.dao.PersonDao;
import pers.domain.Person;
import javax.annotation.Resource;
import java.util.List;
@Service
public class PersonService {
@Resource
private PersonDao personDao;
public void addPerson(Person person) {
personDao.addPerson(person);
}
public List<Person> queryAll() {
return personDao.queryAll();
}
public void delete(int id) {
personDao.delete(id);
}
public Person queryById(int id) {
return personDao.queryById(id);
}
public void update(Person person) {
personDao.update(person);
}
}
package pers.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import pers.dao.HouseDao;
import pers.domain.House;
import java.util.List;
@Service
public class HouseService {
@Autowired
private HouseDao houseDao;
public List<House> queryAll(){
return houseDao.queryAll();
}
}
- 创建dao和daoImpl
package pers.dao;
import pers.domain.Person;
import java.util.List;
public interface PersonDao {
//添加
void addPerson(Person person);
//查询全部
List<Person> queryAll();
//根据编号删除
void delete(int id);
//根据编号查询
Person queryById(int id);
//修改
void update(Person person);
}
package pers.dao.impl;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import pers.dao.PersonDao;
import pers.domain.Person;
import java.util.List;
@Repository("personDao")
public class personDaoImpl implements PersonDao {
@Autowired
private SessionFactory sessionFactory;
@Override
public void addPerson(Person person) {
Session currentSession = sessionFactory.getCurrentSession();
currentSession.save(person);
}
@Override
public List<Person> queryAll() {
Session currentSession = sessionFactory.getCurrentSession();
return currentSession.createQuery("from Person").list();
}
@Override
public void delete(int id) {
Session currentSession = sessionFactory.getCurrentSession();
Person person = new Person();
person.setPersonId(id);
currentSession.delete(person);
}
@Override
public Person queryById(int id) {
Session currentSession = sessionFactory.getCurrentSession();
return (Person) currentSession.get(Person.class,id);
}
@Override
public void update(Person person) {
Session currentSession = sessionFactory.getCurrentSession();
currentSession.update(person);
}
}
package pers.dao;
import pers.domain.House;
import java.util.List;
public interface HouseDao {
//查询全部
List<House> queryAll();
}
package pers.dao.impl;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import pers.dao.HouseDao;
import pers.domain.House;
import java.util.List;
@Repository
public class HouseDaoImpl implements HouseDao {
@Autowired
private SessionFactory sessionFactory;
@Override
public List<House> queryAll() {
Session currentSession = sessionFactory.getCurrentSession();
return currentSession.createQuery("from House").list();
}
}
- 完善pers.test.SpringHibernateTest.java测试类
package pers.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pers.domain.House;
import pers.domain.Person;
import pers.service.HouseService;
import pers.service.PersonService;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.List;
public class SpringHibernateTest {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
@Test
public void testDataSource() throws SQLException {
DataSource dataSource = ctx.getBean(DataSource.class);
System.out.println(dataSource.getConnection());
}
@Test
public void testFindAllPerson() {
PersonService personService = ctx.getBean(PersonService.class);
List<Person> personList = personService.queryAll();
for(Person person : personList) {
System.out.println(person);
}
}
@Test
public void testFindAllHouse() {
HouseService houseService = ctx.getBean(HouseService.class);
List<House> houseList = houseService.queryAll();
for(House house : houseList) {
System.out.println(house);
}
}
@Test
public void testAddPerson() {
Person person = new Person();
person.setRealName("tt");
person.setTelephone("3333333333");
person.setAddress("湖南省");
PersonService personService = ctx.getBean(PersonService.class);
personService.addPerson(person);
}
@Test
public void testDeletePerson() {
PersonService personService = ctx.getBean(PersonService.class);
personService.delete(3);
}
@Test
public void testQueryByIdPerson() {
PersonService personService = ctx.getBean(PersonService.class);
Person person = personService.queryById(4);
System.out.println(person);
}
@Test
public void testUpdatePerson() {
PersonService personService = ctx.getBean(PersonService.class);
Person person = personService.queryById(4);
person.setAddress("黑龙江");
personService.update(person);
}
}
至此完成了Spring和Hibernate的整合
网友评论