zoukankan      html  css  js  c++  java
  • Use Spring transaction to simplify Hibernate session management

    Spring对Hibernate有很好的支持
       

    DataSource ->SessionFactory-> HibernateTranscationManager
    Hibernate中通过SessionFactory创建和维护Session。Spring对SessionFactory的配置进行了整合,无需再通过Hibernate.cfg.xml对SessionFactory进行设定。SessionFactory节点的mappingResources属性包含了映射文件的路径,list节点下可配置多个映射文件。hibernateProperties节点则容纳了所有的属性配置。可以对应传统的Hibernate.cfg.xml文件结构对这里的SessionFactory配置进行解读。

    如果一个方法中既用了HibernateTemplate,又用了JdbcTemplate,应该怎么配单实例的db事务呢(多例免谈)用 DataSouceTransactionManager是不行的,而用HibernateTransactionManager就可以保证
    原因的话看下它们源代码,会发现HibernateTransactionManager中的处理可以保证SessionFactoryUtil和datasourceutil都能在一个事务里取到同一个连接

    所以如果使用hibernateTransactionManager的话,就完全可以保证SessionFactoryUtil和datasourceutil都能在一个事务里取到同一个连接!所有的疑问烟消云散了,
    所以大家还是使用hibernateTransactionManager从而随心所欲的使用jdbctemplate和hibernatetemplate吧

        下面是HibernateSessionFactory 和 HibernateTransactionManager的配置:

        在applicationContext-hibernate.xml中:

     1<bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
     2    <property name="dataSource"><ref bean="dataSource"/></property>
     3    <property name="mappingResources">
     4        <list>
     5            <value>com/mycompany/model/User.hbm.xml</value>
     6                ……………………………
     7        </list>
     8    </property>
     9    <property name="hibernateProperties">
    10    <props>
    11        <prop key="hibernate.dialect">@HIBERNATE-DIALECT@</prop>
    12        <!--prop key="hibernate.show_sql">true</prop-->
    13        <!--prop key="hibernate.hbm2ddl.auto">update</prop-->
    14    </props>
    15    </property>
    16</bean>

        Spring 提供了一个 HibernateTransactionManager,采用面向Hibernate的TransactionManager实现:org.springframework.orm.hibernate.HibernateTransactionManager。他用线程捆绑了一个Hibernate Session,用它来支持transactions。
    1<bean id="transactionManager" 
    2     class="org.springframework.orm.hibernate.HibernateTransactionManager">
    3     <property name="sessionFactory"><ref local="sessionFactory"/></property>
    4 </bean>

    sessionFactory Bean引用了HibernateSessionFactory,而transactionManager Bean引用了HibernateTransactionManage。 transactionManager Bean中有个sessionFactory属性。HibernateTransactionManager有个sessionFactory setter 和 getter方法,用来在Spring启动的时候实现“依赖注入” (dependency injection)的。 在sessionFactory 属性里引用sessionFactory Bean。这两个对象在Spring容器初始化后就被组装了起来了。
      
        User使用一个TransactionProxyFactoryBean,它定义了一个setTransactionManager()。能很方便的处理申明的事物还有Service Object。TransactionProxyFactoryBean 还有个setter. 这会被Business service object(UserManager)引用, UserManager定义了业务层,并且它还有个属性,由setUserDAO()引用。

    DataSource->SessionFactory->HibernateTemplate->HibernateDaoSupport

        系统持久层中所有的类都继承自Spring提供的HibernateDaoSupport类,HibernateSupport实现了HibernateTemplate和SessionFactory实例的关联。HibernateTemplate对Hibernate Session操作进行了封装,提供了一个简单的方式实现了Hibernate-based DAO对象。借助HibernateTemplate我们可以脱离每次数据操作必须首先获得Session实例、启动事务、提交/回滚事务以及烦杂的try/catch/finally的繁琐操作。一个简单的Hibernate访问方法就完全解决了些麻烦! 无论是在多个DAO接口还是在多方事务的情况下,Spring使得多种DAO对象无缝地协同工作。

    Spring为Hibernate的DAO提供工具类:HibernateDaoSupport。该类主要提供如下两个方法,方便DAO的实现:

          public final HibernateTemplate getHibernateTemplate()

          public final void setSessionFactory(SessionFactory sessionFactory)

    其中,setSessionFactory方法用来接收Spring的ApplicationContext的依赖注入,可接收配置在Spring的SessionFactory实例,getHibernateTemplate方法则用来根据刚才的SessionFactory产生Session,最后生成HibernateTemplate来完成数据库访问。


        对于简单的单步的动作,象find, load, saveOrUpdate或者delete的调用,HibernateTemplate提供更为便利的选择以代替象一行的回调的执行。此外HibernateDaoSupport类提供了setSessionFactory方法来接受一个SessionFactory,同时提供了getSessionFactory和getHibernateTemplate方法供其继承类使用。将这些结合起来,允许对于典型的需求给出了非常简单的DAO实现,如获得所有用户的方法:
        public List getUsers(User user) {
            return getHibernateTemplate().find("from User u order by upper(u.username)");
        }

     HibernateTemplate:public void saveUser(Person person){
     4
     5              getHibernateTemplate().saveOrUpdate(person);
     6
     7         }

    采用事物配置,我们就不需要写那么多的try catch和finally了,因为容器会自动帮我们在执行方法前给我们加上。

    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
        <property name="sessionFactory">
           <ref bean="sessionFactory"/>
        </property>
    </bean>


    也可以:
    <bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory">
           <ref bean="sessionFactory"/>
        </property>
    </bean>

    两种实现方式其实没有区别,尤其是第二种不要自己去关闭session,session在事务结束后都会自动关闭。 但是一定要注意延迟加载的问题,当对象在session关闭前没有从数据库中取得,而jsp中需要展示对象时,会提示LazyInitializationException,你可以通过OpenSessionInViewFilter来保证延迟加载不会出现错误,即:
    <filter>
         <filter-name>opensession</filter-name>
         <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
    </filter>
    <filter-mapping>
         <filter-name>opensession</filter-name>
         <url-pattern>*.do</url-pattern>
    </filter-mapping>

  • 相关阅读:
    python的包和模块
    python 匿名函数
    hdu 1455 Sticks
    python 返回函数
    python 自定义排序函数
    batchsize对收敛速度的影响
    mini_batch GD
    dropout
    sift
    hog
  • 原文地址:https://www.cnblogs.com/wblade/p/3708426.html
Copyright © 2011-2022 走看看