成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Hibernate延遲加載與DAO模式的整合

開發 后端
本文介紹在Spring框架下Hibernate延遲加載與DAO模式的整合。Hibernate 對象關系映射提供延遲的與非延遲的對象初始化。非延遲加載在讀取一個對象的時候會將與這個對象所有相關的其他對象一起讀取出來。

Hibernate延遲加載:

Hibernate 對象關系映射提供延遲的與非延遲的對象初始化。非延遲加載在讀取一個對象的時候會將與這個對象所有相關的其他對象一起讀取出來。這有時會導致成百的(如果不是成千的話) select 語句在讀取對象的時候執行。這個問題有時出現在使用雙向關系的時候,經常會導致整個數據庫都在初始化的階段被讀出來了。當然,你可以不厭其煩地檢查每一個對象與其他對象的關系,并把那些最昂貴的刪除,但是到***,我們可能會因此失去了本想在 ORM 工具中獲得的便利。

一個明顯的解決方法是使用 Hibernate 提供的延遲加載機制。這種初始化策略只在一個對象調用它的一對多或多對多關系時才將關系對象讀取出來。這個過程對開發者來說是透明的,而且只進行了很少的數據庫操作請求,因此會得到比較明顯的性能提升。這項技術的一個缺陷是延遲加載技術要求一個 Hibernate 會話要在對象使用的時候一直開著。這會成為通過使用 DAO 模式將持久層抽象出來時的一個主要問題。為了將持久化機制完全地抽象出來,所有的數據庫邏輯,包括打開或關閉會話,都不能在應用層出現。最常見的是,一些實現了簡單接口的 DAO 實現類將數據庫邏輯完全封裝起來了。一種快速但是笨拙的解決方法是放棄 DAO 模式,將數據庫連接邏輯加到應用層中來。這可能對一些小的應用程序有效,但是在大的系統中,這是一個嚴重的設計缺陷,妨礙了系統的可擴展性。

在 Web 層進行延遲加載

幸運的是, Spring 框架為 Hibernate延遲加載與 DAO 模式的整合提供了一種方便的解決方法。對那些不熟悉 Spring 與 Hibernate 集成使用的人,我不會在這里討論過多的細節,但是我建議你去了解 Hibernate 與 Spring 集成的數據訪問。以一個 Web 應用為例, Spring 提供了 OpenSessionInViewFilter 和 OpenSessionInViewInterceptor 。我們可以隨意選擇一個類來實現相同的功能。兩種方法唯一的不同就在于 interceptor 在 Spring 容器中運行并被配置在 web 應用的上下文中,而 Filter 在 Spring 之前運行并被配置在 web.xml 中。不管用哪個,他們都在請求將當前會話與當前(數據庫)線程綁定時打開 Hibernate 會話。一旦已綁定到線程,這個打開了的 Hibernate 會話可以在 DAO 實現類中透明地使用。這個會話會為延遲加載數據庫中值對象的視圖保持打開狀態。一旦這個邏輯視圖完成了, Hibernate 會話會在 Filter 的 doFilter 方法或者 Interceptor 的 postHandle 方法中被關閉。下面是每個組件的配置示例:

Interceptor的配置:

  1. <  beans >    
  2. <  bean  id ="urlMapping"    
  3. class ="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping" >    
  4. <  property  name ="interceptors" >    
  5. <  list >    
  6. <  ref  bean ="openSessionInViewInterceptor" />    
  7. < / list >    
  8. < / property >    
  9. <  property  name ="mappings" >    
  10.  
  11. < / bean >    
  12.  
  13. <  bean  name ="openSessionInViewInterceptor"    
  14. class ="org.springframework.orm.hibernate.support.OpenSessionInViewInterceptor" >    
  15. <  property  name ="sessionFactory" ><  ref  bean ="sessionFactory" />< / property >    
  16. < / bean >    
  17. < / beans >    

Filter的配置

  1. <  web-app >    
  2.  
  3. <  filter >    
  4. <  filter-name > hibernateFilter < / filter-name >    
  5. <  filter-class >    
  6. org.springframework.orm.hibernate.support.OpenSessionInViewFilter   
  7. < / filter-class >    
  8. < / filter >    
  9.  
  10. <  filter-mapping >    
  11. <  filter-name > hibernateFilter < / filter-name >    
  12. <  url-pattern > *. spring  < / url-pattern >    
  13. < / filter-mapping >    
  14.  
  15. < / web-app >    

實現 Hibernate 的 Dao 接口來使用打開的會話是很容易的。事實上,如果你已經使用了 Spring 框架來實現你的 Hibernate Dao, 很可能你不需要改變任何東西。方便的 HibernateTemplate 公用組件使訪問數據庫變成小菜一碟,而 DAO 接口只有通過這個組件才可以訪問到數據庫。下面是一個示例的 DAO :

  1. public   class  HibernateProductDAO  extends  HibernateDaoSupport  implements  ProductDAO  {   
  2.  
  3. public  Product getProduct(Integer productId)  {   
  4. return  (Product)getHibernateTemplate().load(Product. class , productId);   
  5. }    
  6.  
  7. public  Integer saveProduct(Product product)  {   
  8. return  (Integer) getHibernateTemplate().save(product);   
  9. }    
  10.  
  11. public   void  updateProduct(Product product)  {   
  12. getHibernateTemplate().update(product);   
  13. }    
  14. }    

在業務邏輯層中使用Hibernate延遲加載

即使在視圖外面, Spring 框架也通過使用 AOP 攔截器 HibernateInterceptor 來使得延遲加載變得很容易實現。這個 Hibernate 攔截器 透明地將調用配置在 Spring 應用程序上下文中的業務對象中方法的請求攔截下來,在調用方法之前打開一個 Hibernate 會話,然后在方法執行完之后將會話關閉。讓我們來看一個簡單的例子,假設我們有一個接口 BussinessObject :

  1. public     interface   BusinessObject    {   
  2.   public     void   doSomethingThatInvolvesDaos();   
  3. }    

類BusinessObjectImpl實現了BusinessObject接口:

  1. public     class   BusinessObjectImpl   implements   BusinessObject    {   
  2.   public     void   doSomethingThatInvolvesDaos()    {   
  3.   //   lots of logic that calls   
  4.   //   DAO classes Which access   
  5.   //   data objects lazily     
  6.   }     
  7. }   

通過在Spring應用程序上下文中的一些配置,我們可以讓將調用BusinessObject的方法攔截下來,再令它的方法支持延遲加載。看看下面的一個程序片段:

  1. <  beans >    
  2. <  bean  id ="hibernateInterceptor"  class ="org.springframework.orm.hibernate.HibernateInterceptor" >    
  3. <  property  name ="sessionFactory" >    
  4. <  ref  bean ="sessionFactory" />    
  5. < / property >    
  6. < / bean >    
  7. <  bean  id ="businessObjectTarget"  class ="com.acompany.BusinessObjectImpl" >    
  8. <  property  name ="someDAO" ><  ref  bean ="someDAO" />< / property >    
  9. < / bean >    
  10. <  bean  id ="businessObject"  class ="org.springframework.aop.framework.ProxyFactoryBean" >    
  11. <  property  name ="target" ><  ref  bean ="businessObjectTarget" />< / property >    
  12. <  property  name ="proxyInterfaces" >    
  13. <  value > com.acompany.BusinessObject < / value >    
  14. < / property >    
  15. <  property  name ="interceptorNames" >    
  16. <  list >    
  17. <  value > hibernateInterceptor < / value >    
  18. < / list >    
  19. < / property >    
  20. < / bean >    
  21. < / beans >  

當 businessObject 被調用的時候, HibernateInterceptor 打開一個 Hibernate 會話,并將調用請求傳遞給 BusinessObjectImpl 對象。當 BusinessObjectImpl 執行完成后, HibernateInterceptor 透明地關閉了會話。應用層的代碼不用了解任何持久層邏輯,還是實現了延遲加載。

在單元測試中測試Hibernate延遲加載

***,我們需要用 J-Unit 來測試我們的延遲加載程序。我們可以輕易地通過重寫 TestCase 類中的 setUp 和 tearDown 方法來實現這個要求。我比較喜歡用這個方便的抽象類作為我所有測試類的基類。

  1. public   abstract   class  MyLazyTestCase  extends  TestCase  {   
  2.  
  3. private  SessionFactory sessionFactory;   
  4. private  Session session;   
  5.  
  6. public   void  setUp()  throws  Exception  {   
  7. super .setUp();   
  8. SessionFactory sessionFactory  =  (SessionFactory) getBean( " sessionFactory " );   
  9. session  =  SessionFactoryUtils.getSession(sessionFactory,  true );   
  10. Session s  =  sessionFactory.openSession();   
  11. TransactionSynchronizationManager.bindResource(sessionFactory,  new  SessionHolder(s));   
  12.  
  13. }    
  14.  
  15. protected  Object getBean(String beanName)  {   
  16. // Code to get objects from Spring application context    
  17. }    
  18.  
  19. public   void  tearDown()  throws  Exception  {   
  20. super .tearDown();   
  21. SessionHolder holder  =  (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);   
  22. Session s  =  holder.getSession();   
  23. s.flush();   
  24. TransactionSynchronizationManager.unbindResource(sessionFactory);   
  25. SessionFactoryUtils.closeSessionIfNecessary(s, sessionFactory);   
  26. }    
  27. }     

【編輯推薦】

  1. Hibernate的繼承關系
  2. 有關Hibernate延時加載與lazy機制
  3. Hibernate訪問多個數據庫
  4. Hibernate的lazy屬性總結
  5. Hibernate中hbm的generator子元素
責任編輯:book05 來源: csdn
相關推薦

2011-11-24 21:03:10

ibmdw

2009-09-24 11:41:46

Hibernate延遲

2009-06-17 11:18:02

Hibernate延遲

2009-09-25 10:47:25

Hibernate延遲

2009-09-28 09:56:53

Hibernate屬性

2009-09-28 09:40:28

Hibernate集合延遲加載

2009-09-25 10:17:21

Hibernate延遲

2009-09-28 09:35:10

Hibernate實現實體對象延遲加載

2009-07-09 18:24:00

WebWork與Spr

2009-09-22 09:13:43

Hibernate D

2009-07-02 09:38:17

Hibernate延時

2012-08-15 11:36:13

Hibernate

2016-12-14 09:03:34

springhibernate異常

2009-07-14 16:55:32

MyEclipse S

2009-06-18 11:43:40

Hibernate uHibernate s

2023-06-29 07:48:35

異步加載JavaScript

2012-06-05 10:22:45

jQuery

2022-12-02 08:00:00

JavaScriptAstro前端

2009-09-21 17:10:14

struts Hibe

2009-03-06 14:34:31

StrutsHibernateSpring
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久草新在线 | 一区日韩 | 琪琪午夜伦伦电影福利片 | 99婷婷| 日韩av成人在线观看 | 婷婷色国产偷v国产偷v小说 | 国产一区亚洲 | 久久综合av | 亚洲网在线 | 精品亚洲二区 | 在线亚洲电影 | 在线视频91 | 欧洲一区二区三区 | 日韩一区在线播放 | 欧美精品片 | 亚洲网站免费看 | 拍戏被cao翻了h承欢 | 99亚洲精品 | 亚洲人成人一区二区在线观看 | 亚洲 中文 欧美 日韩 在线观看 | 久久久久久国产精品三区 | 欧美成人精品一区二区男人看 | 成人伊人 | 国产色黄| 国产精品一区二区在线 | 精品一二三区在线观看 | 日本中文字幕一区 | 狠狠色综合网站久久久久久久 | 欧美嘿咻| 一级毛片在线看 | 性网址| 黄色男女网站 | 亚洲综合在线视频 | 欧美精品一区二区三区在线 | 日韩和的一区二区 | 午夜色播 | 成人av看片 | 99re视频| 日一日操一操 | 极情综合网 | 国产成人高清 |