zoukankan      html  css  js  c++  java
  • Spring整合Hibernate

    DataSource

       标准化的取得连接的方式

        spring连接池    

            dbcp配置

    Hibernate使用Annotation的方式

    简单整合

    •   1. 先在spring容器里面初始化一个SessionFactory
    •   2. 注入需要的连接信息
        <bean id="dataSource" destroy-method="close"
            class="org.apache.commons.dbcp.BasicDataSource">
            <property name="driverClassName"
                value="${jdbc.driverClassName}" />
            <property name="url" value="${jdbc.url}" />
            <property name="username" value="${jdbc.username}" />
            <property name="password" value="${jdbc.password}" />
        </bean>
    
        <bean id="sessionFactory"   class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="annotatedClasses">
                <list>
                    <value>com.bjsxt.model.User</value>
    <value>com.bjsxt.model.Log</value>
    </list>
    </property>
            <property name="hibernateProperties">
                <props>
                    <prop key="hibernate.dialect">
                        org.hibernate.dialect.MySQLDialect
                    </prop>
                    <prop key="hibernate.show_sql">true</prop>
                </props>
            </property>
        </bean>

           sessionFactory的class并不是hibernate自己的,而是使用的Spring的AnnotationSessionFactoryBean

         

          它里面有很多的属性:

         

          

          他需要注入的信息有:(也就是这个类中含有的set方法)

               1. dataSource  数据源

               2. annotateClasses

                   它需要注入的信息是一个集合,表示哪些实体类上加了注解,需要用到hibernate

               3.  hibernateProperties

                   这是一个Properties类型的对象,表示Hibernate的一些属性,比如Hibernate方言等。

             上面的例子中是用的注入 annotateClasses这个属性,但是如果类非常多,这个就非常不方便了

             我们可以注入 packagesToScan这个属性

             

          <property name="packagesToScan">
                <list>
                    <value>com.bjabc.model</value>                
                </list>
            </property>

             

            然后再在需要的实体类上加上Hibernate需要的注解即可,比如@Entity之类的

                   

            这种方式是Annotation的方式,不需要hibernate的配置文件

           如果使用xml方式   class="org.springframework.orm.hibernate3.annotation.SessionFactoryBean

           而且还有加入一个name = mappingResources value=....hbm.xml的子属性,表示hibernate的配置文件

    事务管理

      

           首先要搞清事务的开始和结束

           有两种管理方式

    •    Annotation
    •    XML

             

              先说说Annotation

           首先要在spring的bean.xml中引入annotation驱动

           然后把sessionFactory交给事务的txManager管理

    <bean id="txManager"
            class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory" />
     </bean>
        
     <tx:annotation-driven transaction-manager="txManager"/>

           接下来就是配置需要添加事务管理的类了

           比如是加在管理层上

           

    @Transactional(readOnly = true)
    public class UserServiceImpl  implements UserService {
    
        public Foo getFoo(String name) {
            // do something
        }
    
       
        @Transactional(propagation = Propagation.REQUIRED)
        public void add(User user) {
            userDAO.save(user);      
    } }

    那么对于DAO层

    public class UserDAOimpl  implements UserDAO {
    
        private SessionFactory sessionFactory;
    
       
        public void save(User user) {
            
           session s = sessionFactory.getCurrentSession();
           s.save(user);      
    
        }
    }

             这里必须要getCurrentSession,就是说这个时候连接已经创建了,不可以再重新create了。

             类或者方法上上只需要加入@Transactional 就可以了

          但是有很多属性

          最要的属性必须要加上的 (不加也一样,默认就是)

            propagation = Propagation.REQUIRED

          其他的

           readOnly = false   

          表示建立一个readOnly的连接,对于不需要增删改只需要查的动作

          有两个好处, 1。 提高性能, 2,防止意外的修改操作

                    roolBackFor

           默认下都是对于runtimeException

           

            XML方式

            也就是spring 的AOP方式

          

        <bean id="txManager"
            class="org.springframework.orm.hibernate3.HibernateTransactionManager">
            <property name="sessionFactory" ref="sessionFactory" />
        </bean>
    
    
        <tx:advice id="txAdvice" transaction-manager="txManager">
            <tx:attributes>
                <tx:method name="getUser" read-only="true" />
                <tx:method name="add*" propagation="REQUIRED"/>
            </tx:attributes>
        </tx:advice>
    
       
    定义一个切面,表示事务,并且加入到相应方法
    <aop:config> <aop:pointcut id="bussinessService" expression="execution(public * com.bjsxt.service..*.*(..))" /> <aop:advisor pointcut-ref="bussinessService" advice-ref="txAdvice" /> </aop:config>

         然后在类上就不用加那些标记了

         实际开发过程中,用的xml方法比较多

         因为不用在每个方法上加标记

    HibernateTemplate

             里面有一种设计模式:Template Method 模板方法

       

       把对sessionFactory的管理交给hibernateTempate

       spring的容器里

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

       看一下HibernateTempate这个类的源码,可以看到里面有几个属性,需要注入

       比如有一个setSessionFactory()方法

       而这个类也已经把sessionFactory里的很多方法都封装好了

       比如load()方法,save()方法等。

         

         所以在程序里直接调用这些方法就行了

         那么在UserDAOimpl里面

         就不需要像以前那样有一个sessionFactory对象了

         只需要有一个HibernateTemplate对象就可以了,然后通过注入获得这个对象

        然后调用这个对象的save()方法等等。

        

         

        那么它内部的原理是什么呢?

        可以看一下 hibernateTemplate.save方法的源码

         

            这个方法的实现过程可以这么理解

         所谓模板方法,其实就是说我们之前用sessionFactory在各个DAO中建立连接和断开连接的操作都是一样的,所以每个DAO的开始和结束都差不多i,所以我们定义一个方法,他的开始和结束一样,然后再在中间插入我们自定义的操作就行了。

         

         

         

            hibernate可以封装jdbc,jdo,orm等很多中间层的产品

            但是有两个相同的封装过程

            1. 提供特定的Template

          2. 所有的异常会封装从成DataAcessExceptin

               这是一个runtime异常,会回滚

           callback 回调/钩子

          

  • 相关阅读:
    winform,WPF 释放内存垃圾,减少资源占用方法
    Winform中使用WPF控件并动态读取Xaml
    Winform程序双向绑定
    STM32L15XXX 入门笔记
    STM32固件库下载地址
    C#实现虚拟控件列表显示100w个控件方法
    DotNetBar滚动条的疑似BUG
    VS Sln图标空白修复办法
    Swift下使用Xib设计界面
    关于Mac OS虚拟机下共享文件夹的方法
  • 原文地址:https://www.cnblogs.com/tech-bird/p/4169673.html
Copyright © 2011-2022 走看看