SSH 框架整合技术:
1. Spring与Hibernate整合(对比Spring与JDBC模板):
Service业务层代码和测试类都不变,添加实体类的映射配置文件:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 5 6 <hibernate-mapping package="com.tongji.beans"> 7 <class name="Student"> 8 <id name="id"> 9 <generator class="native"/> 10 </id> 11 <property name="name"/> 12 <property name="age"/> 13 </class> 14 </hibernate-mapping>
修改Dao接口的实现类:
由于 Dao 实现类要通过 Hibernate 来操作 DB,所以在该类中需要获取到 Session 工厂对象 SessionFactory。当然,最终目的是获取到 Hibernate 的 Session 对象。而 SessionFactory对象的创建,也是由 Spring 容器来管理的,所以,需要在 Dao 实现类中添加 SessionFactory属性,以便 Spring 容器通过 setXXX() 将 Session 工厂注入。
1 package com.tongji.dao; 2 3 import java.util.List; 4 5 import org.hibernate.Session; 6 import org.hibernate.SessionFactory; 7 8 import com.tongji.beans.Student; 9 10 public class StudentDaoHbnImpl implements IStudentDao{ 11 private SessionFactory sessionFactory; 12 13 public void setSessionFactory(SessionFactory sessionFactory) { 14 this.sessionFactory = sessionFactory; 15 } 16 17 @Override 18 public void insertStudent(Student student) { 19 sessionFactory.getCurrentSession().save(student); 20 } 21 22 @Override 23 public void deleteStudent(int id) { 24 Student student = sessionFactory.getCurrentSession().get(Student.class, id); 25 //Student student = this.selectStudentById(id); 26 sessionFactory.getCurrentSession().delete(student); 27 } 28 29 @Override 30 public void updateStudent(Student student) { 31 sessionFactory.getCurrentSession().update(student); 32 } 33 34 @Override 35 public String selectStudentNameById(int id) { 36 // Student student = this.selectStudentById(id); 37 // if (student != null) { 38 // return student.getName(); 39 // } 40 // return null; 41 42 String hql = "select name from Student where id= :id"; 43 String name = (String) sessionFactory.getCurrentSession().createQuery(hql). 44 setInteger("id", id). 45 uniqueResult(); 46 return name; 47 } 48 49 @Override 50 public List<String> selectStudentNames() { 51 String hql = "select name from Student"; 52 return sessionFactory.getCurrentSession().createQuery(hql).list(); 53 } 54 55 @Override 56 public Student selectStudentById(int id) { 57 return sessionFactory.getCurrentSession().get(Student.class, id); 58 } 59 60 @Override 61 public List<Student> selectStudents() { 62 String hql = "from Student"; 63 return sessionFactory.getCurrentSession().createQuery(hql).list(); 64 } 65 66 }
修改Spring配置文件:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xmlns:tx="http://www.springframework.org/schema/tx" 7 xsi:schemaLocation=" 8 http://www.springframework.org/schema/beans 9 http://www.springframework.org/schema/beans/spring-beans.xsd 10 http://www.springframework.org/schema/context 11 http://www.springframework.org/schema/context/spring-context.xsd 12 http://www.springframework.org/schema/tx 13 http://www.springframework.org/schema/tx/spring-tx.xsd 14 http://www.springframework.org/schema/aop 15 http://www.springframework.org/schema/aop/spring-aop.xsd"> 16 17 <!-- 注册数据源:C3P0数据源 --> 18 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> 19 <property name="driverClass" value="${jdbc.driverClass}" /> 20 <property name="jdbcUrl" value="${jdbc.url}" /> 21 <property name="user" value="${jdbc.user}" /> 22 <property name="password" value="${jdbc.password}" /> 23 </bean> 24 25 <!-- 注册JDBC属性文件 --> 26 <context:property-placeholder location="classpath:jdbc.properties"/> 27 28 <!-- 参考hibernate的主配置文件来配置 --> 29 <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> 30 <property name="dataSource" ref="dataSource"/> 31 <property name="hibernateProperties"> 32 <props> 33 <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> 34 <prop key="hibernate.current_session_context_class"> org.springframework.orm.hibernate5.SpringSessionContext</prop> 35 <prop key="hibernate.hbm2ddl.auto">update</prop> 36 <prop key="hibernate.show_sql">true</prop> 37 <prop key="hibernate.format_sql">true</prop> 38 </props> 39 </property> 40 <property name="mappingDirectoryLocations" value="com/tongji/beans"/> 41 </bean> 42 43 <!-- 注册Dao --> 44 <bean id="studentDao" class="com.tongji.dao.StudentDaoHbnImpl"> 45 <property name="sessionFactory" ref="sessionFactory"/> 46 </bean> 47 48 <!-- 注册Service --> 49 <bean id="studentService" class="com.tongji.service.StudentServiceImpl"> 50 <property name="dao" ref="studentDao"></property> 51 </bean> 52 53 <!-- 注册事务管理器 --> 54 <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> 55 <property name="sessionFactory" ref="sessionFactory"/> 56 </bean> 57 58 <!-- 事务通知 --> 59 <tx:advice id="txAdvice" transaction-manager="transactionManager"> 60 <tx:attributes> 61 <!-- 这些被指定的方法应用哪些事务特性 --> 62 <tx:method name="add*" isolation="DEFAULT" propagation="REQUIRED"/> 63 <tx:method name="remove*" isolation="DEFAULT" propagation="REQUIRED"/> 64 <tx:method name="modify*" isolation="DEFAULT" propagation="REQUIRED"/> 65 <tx:method name="find*" isolation="DEFAULT" propagation="REQUIRED" read-only="true"/> 66 </tx:attributes> 67 </tx:advice> 68 69 <!-- AOP配置 --> 70 <aop:config> 71 <!-- 这里的切入点指的是,要将事务通知织入到哪些类的哪些方法上 --> 72 <aop:pointcut expression="execution(* *..service.*.*(..))" id="servicePointcut"/> 73 <aop:advisor advice-ref="txAdvice" pointcut-ref="servicePointcut"/> 74 </aop:config> 75 </beans>
解释:
(1)配置 SessionFactory
Spring 的精髓是,所有的 Bean 均由 Spring 容器统一管理,所以在 Spring 中若要使用Hibernate,就需要将 SessionFactory 交由 Spring 来管理。
配置 SessionFactory 的 Bean,将 hibernate.cfg.xml 文件替换掉。使用的实现类为LocalSessionFactoryBean,注意,是 hibernate5 包下的。其用于设置的属性主要有三个:数据源,映射文件,及 hibernate 特性。其设置内容,与 Hibernate 主配置文件的基本相同。
至于 Hibernate 特性的设置,除了 hibernate.current_session_context_class 外,其余 key与 Hibernate 主配置文件中的属性名相同,值也相同。
属性 hibernate.current_session_context_class,用于指定当前 Session 所执行的上下文环境。其值不再是 thread,而是 SpringSessionContext,表示 Session 将交由 Spring 容器来管理。
(2)配置事务管理器:
由于 Hibernate 的 Session 要求必须在事务环境下才能运行,所以在 Spring 中使用Hibernate ,必须要配置事务管理器,以开启事务环境。此时使用的事务管理器为HibernateTransactionManager。需要注意的是,使用 Jdbc 的事务管理器,需要注入一个数据源 dataSource,而使用 Hibernate 的事务管理器,则需要注入一个 sessionFactory 属性。
补充:在 Spring 中一般不使用 Hibernate 模板对象