Spring與Hibernate、Mybatis整合


在Web項目中一般會把各個web框架結合在一起使用,比如spring+hibernate,spring+ibatis等,如此以來將其他的框架整合到spring中來,便有些少許的不便,當然spring已經把這種整合變得很簡單了。本人結合在項目中使用過的spring和ibatis,以及和mybatis的整合,進而小測了一下和hibernate的整合,望批評指正。

一、spring、hibernate整合 

Spring中不但可以選擇SpringJDBC作為持久化技術,還可以選擇Hibernate、iBatis、JPA、JDO等多種類型的持久化技術。Spring提供了方便的模板類對原ORM進行簡化封裝。讓我們先回憶一下單獨使用Hibernate時的過程,我們需要編寫好一個對象關系的映射文件命名形式如xxx.hbm.xml,然后通過Hibernate的配置文件hibernate.cfg.xml 將所有的xxx.hbm.xml 映射文件組裝起來,最后通過兩行經典的代碼得到SessionFactory的實例,如

Configuration cfg = new Configuration().configure("hiberante.cfg.xml"); 

SessionFactory sessionFactory = cfg.buildSessionFactory();

如果使用注解的話使用AnnotationConfiguration對象,現在Spring為創建SessionFactory提供了一個好用的FactoryBean工廠類:org.springframework.orm.hibernate3.LocalSessionFactoryBean,通過配置一些必要的屬性,即可獲取一個SessionFactoryBean。

1.使用HibernateTemplate 

Hibernate.cfg.xml文件中配置了數據源、對象關聯映射文件以及Hibernate控制屬性信息。因此集成到spring中以后要把該文件中內容都拿過來如下:

<context:componet-scan base-package="com.demo" />

    < context:property-placeholder  location ="classpath:jdbc.properties"   />
    < bean  id ="dataSource"  class ="org.apache.commons.dbcp.BasicDataSource"  destroy-method ="close"   >
     < 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.org.hiberante3.LocalSessionFactoryBean"   >
      < property  name ="dataSource"  ref ="dataSource" />
      < property  name ="mappingResources"   >
          < list >
                 < value >com.demo.hibernate.domain/xxx.hbm.xml </ value >
             </ list >
      </ property >
      < property  name ="hiberanteProperties" >
              < props >
                  < prop  key ="hibernate.dialect" >org.hibernate.dialect.MySQLDialect </ prop >
                  < prop  key ="hibernate.show_sql" >true </ prop >
          </ props >
      </ property >
     </ bean >

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

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

  如上面的配置所示,基於模板類使用hibernate比較簡單,spring提供了使用模板的支持類HibernateDaoSupport類,並通過getHibernateTemplate()方法向子類開放模板類實例的調用。如果不想在每個dao里面都加上HibernateTemplate,可以將其放在一個BaseDao里面,然后通過擴展該類創建一個使用HibernateTemplate的Dao,使用時直接getHibernateTemplate().op(obj) 就可以了。也可以將我們自己的Dao實現直接繼承HibernateDaoSupport類同時實現Dao接口,該方式也很簡單。剩下的就和單獨使用Hibernate區別很小了。

對於lob類型的數據,我們還需要在Spring配置文件重定一個Lob數據處理器,讓SessionFactory擁有處理Lob數據的能力。在SessionFactory里引用該bean:

<bean id="lobHandler" class="org.springframework.jdbc.support.lob.DefaultLobHandler" lazy-init="true" /> 

 2.使用原生Hibernate API

我們可以通過注入SessionFactory 直接通過getCurrentSession()能夠獲取和當前線程綁定的Session。Hibernate自身具備了獲取和事務線程綁定的Session對象的功能,這與在Spring的HibernateTemplate中使用和事務綁定的Session相同。因此使用原生的API,同樣和spring和事務管理器一起工作。和使用template不同的是原生API拋出的異常是Hibernate異常。 

3.使用注解

Hibernate通過AnnotationConfiguration的addAnnotatedClass和addPackage方法加載使用JPA注解的實體類,獲取映射的元數據信息,並在此基礎上創建SessionFactory實例。spring專門提供了一個配套的AnnotationSessionFactoryBean,用以創建基於JPA注解的SessionFactory,該類擴展了LocalSessionFactoryBean類,增強的功能是可以根據實體類的注解獲取ORM的配置信息。也允許混合使用XML配置和注解配置對象關系映射,Hibernate內部自動整合這些元數據信息,並不會產生沖突。 

此外,Spring以防Web層訪問Service層延遲加載的對象,專門提供了一個OpenSessionInViewFilter過濾器,它的主要功能是使每個請求過程綁定一個Hibernate Session,即使最初的事務已經完成了,也可以在Web層進行延遲加載的操作。OpenSessionInViewFilter過濾器將HibernateSession綁定到請求線程中,它將自動被Spring的事務管理器探測到,因此其使用與使用HibernateTransactionManager或JtaTransactionManager進行事務管理的環境,也可以用於非只讀事務的數據操作中。

二、spring集成ibatis/mybatis

ibatis的后續版本改名叫mybatis,現在兩者都被大家經常使用。兩者的最大不同個人感覺是mybatis提供了接口綁定,你不需要再去實現Dao接口,而直接可在Service層調用,將注意力集中在映射文件上即可。ibatis的核心類是SqlMapClient,XmlSqlMapClientFactoryBean通過讀取文件中的sqlMapConfig(當然包括很多的sqlMap),構建一個SqlMapClient,其通過sqlMap來執行映射的每個SQL語句;mybatis的核心類是SqlSessionFactory,SqlSessionFactoryBuilder讀取配置文件(或注解)創建一個SqlSessionFactory,其通過SqlSession來執行已經映射的SQL語句。下面是兩者和spring集成的配置:

  1.Ibatis需要自己在單獨注入各個DAO文件,如

     < bean  id = "xxxDao"  class  ="com.demo.ibatis.dao.impl.xxxDaoImpl" >
              < property  name  ="sqlMapClient"  ref ="sqlMapClient"   />
     </ bean  >
       < bean  id  ="yyyDao"  class = "com.demo.ibatis.dao.impl.yyyDaoImpl"   >
              < property  name  ="sqlMapClient"  ref ="sqlMapClient"   />
     </ bean  >   
     < bean  id  ="zzzDao"  class = "com.demo.ibatis.dao.impl.zzzDaoImpl"   >
              < property  name  ="sqlMapClient"  ref ="sqlMapClient"   />
     </ bean  >
    在spring-prop.xml文件中配置sqlMapClient,如
     < bean  id = "sqlMapClient"  class = "org.springframework.orm.ibatis.SqlMapClientFactoryBean"   > 
         < property  name  ="configLocation"  value = "classpath:ibatis/ibatis-config.xml"   />  
         < property  name  ="dataSource"  ref ="clopsDataSource"   />
         < property  name  ="lobHandler"  ref ="lobHandler" />
     </ bean  >

    如property指定的configuration的位置一樣,要有 < sqlMapConfig >的配置,並將各個xml文件引入進來,ibatis-config.xml如下:
     < sqlMapConfig >
          < settings   useStatementNamespaces = "true"    cacheModelsEnabled = "true"    enhancementEnabled = "true"
             lazyLoadingEnabled
= "true"   maxRequests = "32"  maxSessions = "10"  maxTransactions = "5"    />
          < sqlMap  resource  ="ibatis/xxx.xml"   />
          < sqlMap  resource  ="ibatis/yyy.xml"   />
          < sqlMap  resource  ="ibatis/zzz.xml"   />
......
    </ sqlMapConfig >

     2.而在Mybatis中則不需要這樣配置:
      在spring-prop中指定sqlSessionFactory,如,
      <bean id= "sqlSessionFactory" class= "org.mybatis.spring.SqlSessionFactoryBean" >
             <property name ="dataSource" ref="dataSource" />
             <property name ="typeAliasesPackage" value= "com.demo.mybatis.model" />
             <property name ="mapperLocations" value= "classpath*:mapper/**/*.xml" />
      </bean >
      <bean id ="sqlSession" class= "org.mybatis.spring.SqlSessionTemplate" >
             <constructor-arg index ="0" ref="sqlSessionFactory" />
             <constructor-arg index ="1" value="BATCH" />
      </bean >
      <bean class ="org.mybatis.spring.mapper.MapperScannerConfigurer">
             <property name ="basePackage" value= "com.demo.mybatis.dao" />
             <property name ="sqlSessionTemplate" ref= "sqlSession" />
      </bean >
      其中各種mapper文件在由mapperLocations指定。mybatis相對簡單些。

 使用時類似上面的Hibernate,ibatis可將sqlMapClientTemplate直接注入,或者繼承SqlMapClientDaoSupport類同時實現Dao接口,通過getSqlMapClientTemplate()方法或者sqlMapClient進行操作。注意上述ibatis直接注入的是sqlMapClient,其實sqlMapClientTemplate的構造函數引入了一個sqlMapClient,其使用的方法均來自sqlMapClient。

Mybatis與spring的集成因對數據處理的不同方式而不同,上述方式是采用MapperScannerConfigurer的處理方式,且采用了注解形式,還可以使用MapperFactoryBean、SqlSession、SqlSessionDaoSupport的數據處理方式,使用后兩種方式時需要自己實現Dao接口,而對於MapperFactoryBean其直接指定Dao接口mapperInterface。  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM