Spring 与 Hibernate 集成

集成的好处

  • 由IOC容器来管理Hibernate的SessionFactory
  • 让Hibernate使用上Spring的声明式事务(就不用手动的开启,关闭事务了)

过程讲解

1.Hibernate对应的DAO层继承HibernateDaoSupport类,这个类属于Spring框架的,是Spring对Hibernate的集成,该类需要使用Spring向其注入sessionFactory,DAO层代码,继承HibernateDaoSupport

public class UserManagerImpl extends HibernateDaoSupport implements UserManager {

    @Override
    public void addUser(User user) {
        this.getHibernateTemplate().save(user);     
    }

}

      HibernateDaoSupport 的一个方法是 getHibernateTemplate:

    public final HibernateTemplate getHibernateTemplate() {
      return hibernateTemplate;
    }

2.在Hibernate的配置文件中声明事务是本地事务:

<!-- 存放在threadlocal中 -->
<property name="hibernate.current_session_context_class">thread</property>

3.配置Spring,首先将DAO交给Spring管理,将sessionFactory注入其中

    <bean id="userManager" class="com.bjpowernode.usermgr.manager.UserManagerImpl">
        <property name="sessionFactory" ref="sessionFactory" />
        <property name="logManager" ref="logManager"></property>
    </bean>

      为什么这能注入sessionFactory,因为DAO继承了HibernateDaoSupport,而这个类有一个setSessionFactory()方法,所以实现了注入(在实例化HibernateDaoSupport时就实例化得到sessionFactory了):

    private HibernateTemplate hibernateTemplate;
    public final void setSessionFactory(SessionFactory sessionFactory) {
      this.hibernateTemplate = createHibernateTemplate(sessionFactory);
    }

4.配置Spring,进行事务的配置,Spring针对Hibernate实现了事务管理器,将sessionFactory注入到事务管理器中,同时利用AOP配置事务的管理

    <!-- 配置sessionfactory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
        <property name="configLocation">
            <value>classpath:hibernate.cfg.xml</value>
        </property>
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <!-- name为sessionFactory是由底层的set决定的,第二个sessionFactory是上面配置的 -->
        <!-- 将sessionFactory注入到事务管理器中 -->
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>

    <!-- 哪些类哪些方法使用事务 -->
    <aop:config>
        <aop:pointcut id="allManagerMethod"
            expression="execution(* com.bjpowernode.usermgr.manager.*.*(..))" />
        <!-- 将pintcut和advice注入进来 -->
        <aop:advisor pointcut-ref="allManagerMethod" advice-ref="txAdvice" />
    </aop:config>

    <!-- 对事物的传播性进行设置 -->
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="add*" propagation="REQUIRED" />
            <tx:method name="del*" propagation="REQUIRED" />
            <tx:method name="modify*" propagation="REQUIRED" />
            <!-- 其它的,就剩查询方法了,设置只读属性,如果内存改变,不更新update -->
            <tx:method name="*" propagation="REQUIRED" read-only="true" />
        </tx:attributes>
    </tx:advice>

【注】

  • HibernateTransactionManager通过注入sessionfactory,然后在得到session,把session包装成SessionHolder(),并通过threadlocal来对象的实现和线程的绑定最后到线程中的session取得的Transaction
  • Spring并不直接管理事务,而是提供了多种事务管理器,他们将事务管理的职责委托给Hibernate或者JTA等持久化机制所提供的相关平台框架的事务来实现
  • Spring事务管理器的接口是org.springframework.transaction.PlatformTransactionManager,通过这个接口,Spring为各个平台如JDBC、Hibernate等都提供了对应的事务管理器,但是具体的实现就是各个平台自己的事情了

【总结】

      Spring为Hibernate的DAO提供工具类:HibernateDaoSupport。该类主要提供了两个方法:

public final void setSessionFactory(SessionFactory sessionFactory) 
public final HibernateTemplate getHibernateTemplate()
  • getHibernateTemplate()方法返回hibernateTemplate对象,而hibernateTemplate对象是由setSessionFactory(SessionFactory sessionFactory)调用createHibernateTemplate()方法,此方法又new HibernateTemplate(sessionFactory)创建HibernateTemplate的实例,hibernateTemplate对象已帮助我们实现了事务的开启,关闭,我们只关注对业务的操作即可
  • 我们也可使用this.getSession().save(user);获取事务并进行操作,但是就意味放弃了spring自动管理事务的好处。getSession()也是HibernateDaoSupport类的一个方法:protected final Session getSession()
  • session打开策略为:Spring会根据实际的操作,采用“每次事务打开一次session”的策略,自动提高数据库访问的性能

猜你喜欢

转载自blog.csdn.net/wrs120/article/details/79601878