日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Hibernate之lazy延迟加载

發布時間:2025/4/5 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hibernate之lazy延迟加载 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

一.延遲加載的概念

???當Hibernate從數據庫中加載某個對象時,不加載關聯的對象,而只是生成了代理對象,獲取使用session中的load的方法(在沒有改變lazy屬性為false的情況下)獲取到的也是代理對象,所以在上面這幾種場景下就是延遲加載。

二.理解立即加載的概念

??當Hibernate從數據庫中加載某個對象時,加載關聯的對象,生成的實際對象,獲取使用session中的get的方法獲取到的是實際對象。

三.為什么要使用延遲加載

??延遲加載策略能避免加載應用程序不需要訪問的關聯對象,以提高應用程序的性能。

四.立即加載的缺點

Hibernate在查詢某個對象時,立即查詢與之關聯的對象,我們可以看出這種加載策略存在兩大不足:

1.select的語句數目太多,需要頻繁的訪問數據庫,會影響查詢的性能。

2.在應用程序只需要訪問要的對象,而不需要訪問與他關聯的對象的場景下,加載與之關聯的對象完全是多余的操作,這些多余的操作是會占內存,這就造成了內存空間的浪費。

五.什么時候使用延遲加載什么時候使用立即加載

???如果程序加載一個持久化對象的目的是為訪問他的屬性,則可以采用立即加載。如果程序加載一個持久化對象的目的僅僅是為了獲得他的引用,則可以采用延遲加載。

六.Hibernate在對象-關系映射問價中配置加載策略

???I.類級別:

??????<class>元素中lazy屬性的可選值為true(延遲加載)和false(立即加載);

??????<class>元素中的lazy屬性的默認值為true

???II.一對多關聯級別:

??????<set>元素中的lazy屬性的可選值為:true(延遲加載),extra(增強延遲加載)和false(立即加載);

??????<set>元素中的lazy屬性的默認值為true

???III.多對一關聯級別:

??????<many-to-one>元素中lazy屬性的可選值為:proxy(延遲加載),no-proxy(無代理延遲加載)和false(立即加載)

??????<many-to-one>元素中的lazy屬性的默認值為proxy

? ?在下面的一些案例中都會以員工(Emp)的部門(Dept)的例子講解:

???員工和部門是多對一的關系:

???關于員工和部門的Hibernate配置就不啰嗦了:可以看我的這篇博客:http://www.cnblogs.com/heyongjun1997/p/5767187.html

I.1類級別的查詢策略:

???01.立即加載案例:

?????需求:通過Session的load()方法加載Dept對象時:

? ? ?首先在Dept.hbm.xml文件中配置lazy屬性為false,表示立即加載。

?

?

@Testpublic void loadDept() {// 獲取Session對象Session session = HibernateUtil.currentSession();// 如果通過load方式加載Dept對象Dept dept=(Dept)session.load(Dept.class, 12);// 關閉sessionHibernateUtil.closeSession();}

?

???我們知道使用Load方法加載的是代理對象,只會在屬性里保存一個OID,但是如果在Dept映射文件中配置了類級別的lazy為false就代表加載該對象時立即加載,也就是立即檢索一道數據庫,發出sql:

?

?

? ? ? ?02.延遲加載案例:

????????同樣是獲取Dept對象,但是要把Dept.hbm.xml配置文件的類級別的lazy屬性改為lazy=”true”?或者不寫,應為類級別的lazy屬性默認就是true,

?

?

@Testpublic void loadDept() {// 獲取Session對象Session session = HibernateUtil.currentSession();// 如果通過load方式加載Dept對象session.load(Dept.class, 12);// 關閉sessionHibernateUtil.closeSession();}

?

??此時Dept.hbm.xml配置文件的類級別的lazy屬性為true,則是延遲加載,那么load方法獲取的知識Dept的代理對象,所以他不會去檢索數據庫。

?

?

II.1一對多和多對多關聯的查詢策略

??01.立即加載案例:

?????在獲取部門對象的時候同時獲取員工對象:

設置Dept.hbm.xml?類級別的lazy屬性為false;表示立即加載:

設置<set>元素的lazy屬性為false,表示在加載部門的同時立即加載員工:

?

?

@Testpublic void loadDept() {// 獲取Session對象Session session = HibernateUtil.currentSession();// 如果通過load方式加載Dept對象Dept dept=(Dept)session.load(Dept.class, 12);// 關閉sessionHibernateUtil.closeSession();}

??控制臺輸出結果:

?

?當你想獲取一的一方(Dept)的對象同時,你也要加載多的一方(Emp)的對象,那么你要在一的一方(Emp)的<set>的節點上加上lazy="false"表示立即加載,所以在使用Load方式加載Dept對象的時候,Emp對象也會不加載出來,所以程序在運行到Dept dept=(Dept)session.load(Dept.class, 12);會發出兩條sql語句:

第一條是查詢部門的信息,第二條sql是根據部門編號去數據庫中檢索員工信息。

? 02.延遲加載:

? ? ? 如果把上面的案例<set>節點的屬性lazy改為trur,或者默認不寫,那么在加載Dept對象的時候,就不會再去加載Emp對象,而且只會發出一條sql,這條sql就是指檢索部門的信息。

?

? ? ? 03.增強延遲加載:

? ?當<set>元素中配置lazy的屬性為extra,表明是增強延遲加載策略。

?

??其實增強延遲加載策略與一般的延遲加載策略lazy="true"非常相似。他們主要區別在于,我們看到這個名詞增強延遲加載,顧名思義就是這個策略能在進一步的幫我延遲加載這個對象,也就是代理對象的初始化時機。

? ? ?演示案例:

? ? ? ? ?01. 當set節點的lazy屬性為true,或者不寫的話(取默認值),那么執行以下語句:

? ? ? ? ? ?

@Testpublic void loadDept() {// 獲取Session對象Session session = HibernateUtil.currentSession();// 如果通過load方式加載Dept對象Dept dept=(Dept)session.load(Dept.class, 12);//拿該部門下的員工的人數:也就是集合的大小dept.getEmps().size();// 關閉sessionHibernateUtil.closeSession();}

? ? ? 輸出結果:

? ??

?

? ? ??02. 當set節點的lazy屬性為extra那么執行以下語句:

? ? ? ?

@Testpublic void loadDept() {// 獲取Session對象Session session = HibernateUtil.currentSession();// 如果通過load方式加載Dept對象Dept dept=(Dept)session.load(Dept.class, 12);//拿該部門下的員工的人數:也就是集合的大小dept.getEmps().size();// 關閉sessionHibernateUtil.closeSession();}

? ? ?輸出結果:

? ? ?

?

? ? III.1多對一關聯的查詢策略

? ? ? ? ?在映射文件中,<many-to-one>元素用來設置多對一的關系,在Emp.hbm.xml文件中表明Emp類到Dept類的多對一的關聯關系:

? ??

?

? ? ?01.延遲加載

? ? ? ??需求:獲取Emp對象,但是并不去加載與之關聯的Dept對象。

? ? ? ?首先要設置<many-to-one>節點的lazy屬性為proxy,表示延遲加載。

? ? ??

@Test
public void loadEmp() {
// 獲取Session對象
Session session = HibernateUtil.currentSession();
// 如果通過load方式加載Dept對象
Emp emp=(Emp)session.get(Emp.class, 1);

//獲取Dept對象,因為此時的配置文件lazy是proxy,所以是代理對象
Dept dept=emp.getDept();
// 關閉session
HibernateUtil.closeSession();
}

? ? ? 控制臺輸出結果:

? ? ??

?

??? 結果大家可想而知:<many-to-one>節點的lazy屬性為proxy,表示延遲加載。在加載Emp對象的時候會發出sql去查詢數據庫,但是在獲取Dept對象的時候延遲加載了,所以不會發出sql。

? ? ?

? ? ? ?02.無代理延遲加載:

?

??? ? ? ? ? 在<many-to-one>元素中配置lazy屬性為no-proxy,表示無代理延遲加載。

? ? ? ? ? ? ?

? ? ? ??

@Test public void loadEmp() { // 獲取Session對象 Session session = HibernateUtil.currentSession(); // 如果通過load方式加載Dept對象 Emp emp=(Emp)session.get(Emp.class, 1);//獲取Dept對象,因為此時的配置文件lazy是proxy,所以是代理對象 Dept dept=emp.getDept(); // 關閉session HibernateUtil.closeSession(); }

? ? ? ? ? ??此程序在加載的Emp對象dept屬性為NULL,當程序運行到第3行的時候將觸發Hibernate執行查詢Dept表的select語句,,從而加載Dept對象,由此可見,當lazy屬性為proxy時,可以延長延遲加載Dept代理對象的時間,而lazy屬性為no-proxy時,則可以避免使用由Hibernate提供的Dept代理類實例,是Hibernate對程序提供更加透明的持久化服務。

? ? ?03.立即加載:

? ? ? ? ??首先要設置<many-to-one>節點的lazy屬性為false,表示立即加載。

? ? ? ? ??

? ? ? ? ? ?

@Test
public void loadEmp() {
// 獲取Session對象
Session session = HibernateUtil.currentSession();
// 如果通過load方式加載Dept對象
Emp emp=(Emp)session.get(Emp.class, 1);

//獲取Dept對象,因為此時的配置文件lazy是false,所以是實際對象
Dept dept=emp.getDept();
// 關閉session
HibernateUtil.closeSession();
}

? ? 控制臺輸出結果:

? ? ? ?

?

? ? ? ??

轉載于:https://my.oschina.net/u/3346994/blog/894514

總結

以上是生活随笔為你收集整理的Hibernate之lazy延迟加载的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。