小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Spring整合Hibernate中對HibernateTemplate的思考

 燮羽 2010-10-17

Spring整合Hibernate時,主要做了兩件事:提供事務級session和聲明式的事務控制。
在較早的Hibernate中,對于session的管理一般是one-session-per-operation的方式,即一次具體操作一個session。
Spring為了解決這個問題,引入了HibernateTemplate類。
先來看看它的文檔中一段很有意思的話:
NOTE: As of Hibernate 3.0.1, transactional Hibernate access code can also be coded in plain Hibernate style. Hence, for newly started projects,consider adopting the standard Hibernate3 style of coding data access objects instead, based on SessionFactory.getCurrentSession().(Spring's LocalSessionFactoryBean automatically supports Spring transaction management for the Hibernate3 getCurrentSession() method.)作者說:在新開始的工程,可以考慮用標準的Hibernate3的編碼方式作為HibernateTemplate的替代。因為Hibernate3提供的SessionFactory.getCurrentSession()已經取代了以往那種每次操作都open一個新Session的方式,同時Spring的LocalSessionFactoryBean自動支持Hibernate3的getCurrentSession()的事務管理。也就是說,如果不用HibernateTemplate這咱Spring的專有API,而只用Hibernate3,我們一樣可以受用Spring的事務管理。
來詳細地看看HibernateTemplate,因為它畢竟簡化了Hibernate的操作,但是在有些情況下,我們應該使用Hibernate而不是用HibernateTemplate。根據HibernateTemplate的文檔注釋,它做了兩件事:1.簡化了Hibernate的數據訪問編碼;2.自動地將HibernateExceptions轉化為Spring的異常體系中的DataAccessExceptions(這是一個unchecked exception).
HibernateTemplate實現第一點,是通過回調來實現的,它的核心方法execute(): 

public Object execute(HibernateCallback action, boolean exposeNativeSession) 
      throws DataAccessException
{ 
   //這個Session是受Spring事務管理的
   Session session = getSession(); 
   //這個是怎么回事,還要再仔細看看,我想它應該是關系到Session在這個操作里操作完是否關閉的關鍵
   boolean existingTransaction = SessionFactoryUtils .isSessionTransactional(session, getSessionFactory()); 
   FlushMode previousFlushMode = null; 
   try { 
      previousFlushMode = applyFlushMode(session, existingTransaction); 
      enableFilters(session); 
      //在默認情況下,不把Sessin暴露給用戶
      Session sessionToExpose = (exposeNativeSession ? session : createSessionProxy (session)); 
      //exposeNativeSession默認值為false 
      //這里是真正涉及到Hibernate操作的地方 
      Object result = action.doInHibernate(sessionToExpose); 
      flushIfNecessary(session, existingTransaction); 
      return result; 
   } 
   catch(...){ 
      //將Hibernate代碼拋出的HibernateException,SQLException 
      //轉化為 DataAccessExceptions,如果有運 行時異常,將其拋出 
   }
   finally { 
      if (existingTransaction) { 
         disableFilters(session); 
         if (previousFlushMode != null) { 
            session.setFlushMode(previousFlushMode); 
         } 
      } 
      else { 
         // Never use deferred close for an explicitly new Session. 
         if (isAlwaysUseNewSession()) { 
         //這里的默認值是false,所以此次操作結束后,session不會在此關閉 
         SessionFactoryUtils.closeSession(session); 
         } 
         else { 
            //沒有硬性關閉Session,這是區(qū)別于Hibernate3以前版本的地方 SessionFactoryUtils.closeSessionOrRegisterDeferredClose(session, getSessionFactory()); 
         } 
      } 
   } 
} 
 

真正的數據操作是在HibernateCallback action中實現的,為了執(zhí)行action中的操作,需要一個Session,這個Session是在execute()方法內部獲得(不一定是新產生的)并傳入的。另外,在操作執(zhí)行完之后,這個Session沒有硬性關閉,而是交由SessionFactoryUtils來決定是否立即關閉還是延遲關閉。有時間再看看SessionFactoryUtils .closeSessionOrRegisterDeferredClose()具體做了些什么。
用HibernateTemplate比起直接用Hibernate編碼簡潔了很多。但是,作者在文檔中寫到:The major advantage is its 
automatic conversion to DataAccessExceptions, the major disadvantage that no checked application exceptions can get
thrown from within data access code.因為封閉得太好了,我們根本無法干預HibernateTemplate的方法內部,因此我們
不能拋出檢查型的應用異常。如果我們想在某個方法的內部在某個條件下拋出自定義的應用異常,就要用Hibernate直接編碼了,這是不應該用HibernateTemplate的情況。
作者在文檔中還寫到:It can be used within a service implementation via direct instantiation(實例)with a SessionFactory reference, or get prepared in an application context and given to services as bean reference. 為了使用
HibernateTemplate,我們需要一個SessionFactory,因為使用HibernateTemplate時需要獲取Session,而Session是從SessionFactory獲取的。我們可以在應用配置文件中,根據已配置的SessionFactory配置一個HibernateTemplate,或者在程序中要用時再根據已配置好的SessionFactory來產生一個HibernateTemplate。Spring提供了一個可配置的SessionFactory的工廠類,用以向容器暴露一個單例化的SessionFactory:LocalSessionFactoryBean。這個類的源碼也很有意思,還要繼續(xù)看一下。
為了進一步簡化Hibernate的操作,Spring提供了一個用于DAO的基類HibernateDaoSupport:This base class is mainly 
intended for HibernateTemplate usage。這個類只有唯一的成員變量private HibernateTemplate hibernateTemplate。但是我在想,Spring是不是做的太過分了?包裝得太好了??
 
 下邊附上HibernateTemplate的一般使用方法:

hibernateTemplate的常用方法:

Ø void delete(Object entity):刪除指定持久化實例

Ø deleteAll(Collection entities):刪除集合內全部持久化類實例

Ø find(String queryString):根據HQL查詢字符串來返回實例集合

Ø findByNamedQuery(String queryName):根據命名查詢返回實例集合

Ø get(Class entityClass, Serializable id):根據主鍵加載特定持久化類的實例

Ø save(Object entity):保存新的實例

Ø saveOrUpdate(Object entity):根據實例狀態(tài),選擇保存或者更新

Ø update(Object entity):更新實例的狀態(tài),要求entity是持久狀態(tài)

Ø setMaxResults(int maxResults):設置分頁的大小

HibernateDaoSupport:

SpringHibernateDAO提供工具類:HibernateDaoASupport。該類主要提供如下兩個方法,方便DAO的實現:

1、public final HibernateTemplate getHibernateTemplate()

2、public final void setSessionFactory(SessionFactory sessionFactory)

其中setSessionFactory方法用來接收SpringApplicationContext的依賴注入,可接收配置在SpringSessionFactory實例,getHibernateTemplate方法則用來更具獲得的SessionFactory產生Session,最后生成HibernateTeplate來完成數據庫訪問。

看到這些的時候似乎好像明白了以些,HibernateDaoSupport此類其實并不做太多的事情,它只有兩個方法一個是獲得getHibernateTemplate()和setSessionFacotry()。就像我們在配置文件中配置的那個sessionFactory屬性。而getHibernateTemplate()方法就是常用的save、delete等CRUD基本操作。


HibernateTemplate
用于持久層的訪問,該模板無需打開session及關閉Session。它只要獲得SessionFactory的引用,就可以打開Session,并在持久化訪問結束后關閉Session,程序開發(fā)只需要完成持久曾邏輯,通用的CRUD操作由HibernateTemplate完成.

其實Spring+hibernate訪問數據庫有以下幾種方法:

1、 注入SessionFactory

spring配置文件中,對Dao注入sessionFactory.比較簡單。

:

<bean id="UserInfoDao" class="com.hr2job.dao.impl.UserInfoDaoImpl">

          <property name="sessionFactory" ref="sessionFactory"></property>

</bean>

這里的sessionFacotry注入不是給類的,而是給繼承HibernateDaoSupport類的sessionFactory,在上面源碼中可以看到。以前寫SSH程序的時候就是用這個的,因為是不知道,這個好處就是我們不再需要關心關閉、是否連接成功等問題。主要是很方便。但是這個不好就是java只支持單繼承,所以唯一的繼承給了HibernateDaoSupport有點可惜。而且也沒有必要這樣做。

2、 注入HibernateTemplate

這種方法本質上跟上面的sessionFacotry一樣,只不過進行了一層包裝,好處就是Dao中的類就不用再繼承那個HibernateDaoSuport了,不過要先配置好HibernateTemplate:

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

非常的方便,我現在就在用這個了。其實并沒有改多少,就是曾經的sessionFactroy改成了hibernatemplate

3、 注入jdbcTemplate

這種方法適合那些不喜歡hibernatesave,delete等方法,喜歡自己寫的N人吧。有時候jdbcTemplate查詢的效率會很高。這可能是跟jdbc有關吧。

配置如下:

<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
   <property name="dataSource">
    <ref bean="dataSource" />
   </property>
</bean>

在類中set方法jdbctemplate方法就可以了,spring中的配置跟sessionFactory基本一樣。

總的感覺還是喜歡HibernateTemplate,原因就是好用,不需要寫太多的sql語句,不需要

類去繼承,只要提供一個set方法,再注入一下很方便。應該還有很多的地方不同,歡迎大家討論。


    本站是提供個人知識管理的網絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯系方式、誘導購買等信息,謹防詐騙。如發(fā)現有害或侵權內容,請點擊一鍵舉報。
    轉藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多