1. 程式人生 > >HibernateDaoSupport詳解(增刪改查時Dao常用)

HibernateDaoSupport詳解(增刪改查時Dao常用)

一,Spring為Hibernate的DAO提供工具類:HibernateDaoSupport。該類主要提供了兩個方法:

public final HibernateTemplate getHibernateTemplate() ;
public final void setSessionFactory(SessionFactory sessionFactory) ;
其中,setSessionFactory方法接收來自Spring的applicationContext的依賴注入,接收了配置在Spring 中的SessionFactory例項,getHibernateTemplate方法用來利用剛才的SessionFactory生成Session, 再生成HibernateTemplate來完成資料庫的訪問。

典型的繼承HibernateDaoSupport的DAO程式碼如下:

public class UserDAOImpl extends HibernateDaoSupport implements UserDAO{
public void save(Users transientInstance) {
log.debug("saving Users instance");
try {
getHibernateTemplate().save(transientInstance);
log.debug("save successful");
} catch (RuntimeException re) {
log.error("save failed", re);
throw re;
      }
  }
………………
}
實 際上,DAO的實現依然藉助了HibernateTemplate的模板訪問方式,只是,HibernateDaoSupport將依賴注入 SessionFactory的工作已經完成,獲取HibernateTemplate的工作也已經完成。注意,這種方法須在Spring的配置檔案中配 置SessionFactory。

在繼承HibrnateDaoSupport的DAO實現裡,Hibernate Session的管理完全不需要Hibernate程式碼開啟,而由Spring來管理。Spring會根據實際的操作,採用“每次事務開啟一次 session”的策略,自動提高資料庫訪問的效能。

二,HibernateDaoSupport的優缺點:

編寫Dao類的時候儘量不要使用Hiberenate和Spring對Hibernate的支援:

現在我們在編寫DAO的時候普遍都是直接繼承spring對hibernate的封裝類HibernateDaoSupport, 然後使用該類提供的諸如saveOrUpdate(), saveOrUpdateCopy(), find()等等。另外,在使用excute()方法實現一些更復雜的hibernate功能的時候還會使用hibernate的類,諸如Query, Session, Type等。這樣直接使用spring和hibernate的類存在的問題在於,你的程式碼將不得不依賴與spring和hibernate的某個版本。比 如說,現在hibernate3出來了,改動挺大,實際上最要命的是包結構,hibernate2的包結構是net.sf.hibernate.*,然而 hibernate3是org.hibernate.*。同樣,spring為了支援hibernate3,包名也改為 org.springframework.orm.hibernate3.*。假如,你現在新開發一個專案,這沒什麼關係,如果是升級一個專案問題就來 了。如果你希望將你的一個專案從hibernate2升級為hibernate3,你不得不修改DAO中所有對hibernate和spring- hibernate的引用。如果你的程式碼中出現hibernate2與hibernate3不相容的方法和類,比如saveOrUpdateCopy( )(在hibernate3中已經沒有了),你還將不得不改寫。那麼你可能會說,我不會這樣升級。如果你的軟體生命週期有好多年,hibernate升級到 4,升級到5,你還是依然使用hibernate2?如果你以這種方式開發一個平臺,你能要求所有使用你平臺的軟體專案都只能使用hibernate2? 更進一步說,我現在開發一個產品,今後的客戶將是成千上萬。經過1、2年我需要升級了,這時我的升級包有幾十M,幾乎把所有的DAO都換了個遍,這樣的升級無異於重灌。

分析原因:是我們專案中的DAO依賴於hibernate和spring,因為我們對它們的使用是繼承,是一種很強的關聯,就是一種依賴.

解決方案一:我們只需要稍微進行一些調整,就可以解決這個問題,那就是不使用直接繼承,而使用介面進行分離。可以使用Fa鏰de模式,先建立一個叫 BasicDao的基礎類,從名稱我們可以看出,它是所有DAO的基礎類,實現DAO操作所需的所有諸如save()、delete()、load()、 query()等方法,除了一些基本的方法,諸如翻頁查詢、getCount、解析查詢條件形成HQL語句等功能也在這裡實現,但是不要使用與 hibernate或spring有關的任何方法和類。同時,BasicDao呼叫一個叫DaoSupport的介面,DaoSupport的介面則是提 供持久化所需的基本方法,最原始的元素。然後,我為DaoSupport介面提供各種不同的實現,比如hibernate2的實現 DaoSupportHibernateImp、hibernate3的實現DaoSupportHibernate3Imp,整個結構如下圖所示。 BasicDao可以使用hibernate或spring提供的方法,但是不是直接使用,而是通過呼叫DaoSupport的實現類來使用。然而 BasicDao到底是使用的那個實現類,我們通過spring的IoC,通過配置檔案來決定到底使用哪個實現。同時,BasicDao也不要使用諸如 SpringContext的類來實現IoC,而是通過建立setDaoSupport()和getDaoSupport()方法,然後在spring配 置檔案中建立引用。