Spring整合Hibernate

 

DataSourcespring

   標準化的取得鏈接的方式sql

    spring鏈接池    express

        dbcp配置apache

 

 

Hibernate使用Annotation的方式設計模式

 

簡單整合session

  •   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的AnnotationSessionFactoryBeanapp

     

      它裏面有不少的屬性:性能

     

      

      他須要注入的信息有:(也就是這個類中含有的set方法)url

           1. dataSource  數據源spa

           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 回調/鉤子

相關文章
相關標籤/搜索