Hibernate 延遲載入和立即載入

2022-05-16 13:14:29 字數 4134 閱讀 8914

概念

什麼是延遲載入:所謂延遲載入就是當在真正需要資料的時候,才真正執行資料載入操作。可以簡單理解為,只有在使用的時候,才會發出sql語句進行查詢,資料是分n次讀取。

一、延遲載入:nhibernate延遲載入須有session存在,且配置為lazy=true(預設)

dal中編寫方法如下:

//延遲載入

public order lazyload()

}上面有兩種返回order物件的方式,一種返回order後session繼續存在,一種在返回order後session就被銷毀了,我們先使用未被注釋的方法,然後使用被注釋了的**。

dal.test中編寫如下方法:

[test]

public void lazyloadtest()

然後設定斷點,進行測試除錯,在即時視窗編寫**測試。

當返回order後session繼續存在時,結果如下:

order.orderdate.tostring()

"2009-10-17 11:22:46"

order.customer.firstname

"soldier"

order.products.count

2這裡可以看到,我們可以訪問order物件的關聯物件customer和products

當返回order後session立即被銷毀時,結果如下:

order.orderdate.tostring()

"2009-10-17 11:22:46"

order.customer.firstname

「order.customer.firstname」引發了「nhibernate.lazyinitializationexception」型別的異常

base :

entityid: 2

entityname: "model.entities.customer"

order.products.count

「order.products.count」引發了「nhibernate.lazyinitializationexception」型別的異常

base :

entityid: 2

entityname: "model.entities.order"

這裡我們可以訪問order物件,這是理所當然的。但是不論我訪問order的關聯物件customer還是products時,都會報「nhibernate.lazyinitializationexception」異常,因為訪問時使用的是延遲載入,但是session此時已經被銷毀了,所以報錯,這說明要使用延遲載入就必須保證session是存在的。

二、立即載入:有三種方法進行立即載入,一、配置lazy=」false」;二、使用nhibernateutil類;三、使用帶fetchhql語句

1)       配置lazy=」false」進行立即載入

首先修改order.hbm.xml檔案,將

修改為如下:

然後再測試,結果如下:

order.orderdate.tostring()

"2009-10-17 11:22:46"

order.products.count

2order.customer.firstname

「order.customer.firstname」引發了「nhibernate.lazyinitializationexception」型別的異常

base :

entityid: 2

entityname: "model.entities.customer"

這裡可以看到配置了lazy="false"的products可以訪問,因為它的資料已經和order一起讀取了,但是當我們訪問customer時,報出了上面我們曾經見到過的錯誤,因為在order的對映檔案裡並沒有配置customer為立即載入,所以報錯。

2)       使用nhibernateutil類進行強制立即載入

首先修改lazyload()函式的**如下:

//返回order後isession將會立即被銷毀

using (isession isession = new sessionmanager().getsession())

測試結果如下:

order.orderdate.tostring()

"2009-10-17 11:22:46"

order.products.count

2order.customer.firstname

"soldier"

哈哈,又可以訪問customer物件了。

3)       使用帶fetch的hql查詢

a) 使用hql查詢方法也可以立即載入。hql語句支援的連線型別為:inner join(內連線)、left outer join(左外連線)、right outer join(右外連線)、full join(全連線,不常用)。

b) 「抓取fetch」連線允許僅僅使用乙個選擇語句就將相關聯的物件隨著他們的父物件的初始化而被初始化,可以有效的代替了對映檔案中的外聯接與延遲屬性宣告。

幾點注意:

c) fetch不與setmaxresults() 或setfirstresult()共用,因為這些操作是基於結果集的,而在預先抓取集合時可能包含重複的資料,也就是說無法預先知道精確的行數。

d) fetch還不能與獨立的with條件一起使用。通過在一次查詢中fetch多個集合,可以製造出笛卡爾積,因此請多加注意。對多對多對映來說,同時join fetch多個集合角色可能在某些情況下給出並非預期的結果,也請小心。

e)使用full join fetch 與 right join fetch是沒有意義的。 如果你使用屬性級別的延遲獲取,在第乙個查詢中可以使用 fetch all properties 來強制nhibernate立即取得那些原本需要延遲載入的屬性。

刪除order.hbm.xml中的lazy="false"屬性設定,這樣order的products就不是立即載入了,並將lazyload()函式修改如下:

//延遲載入

public order lazyload()

//使用hql的fetch進行立即載入

using (isession isession = new sessionmanager().getsession())

}除錯測試結果如下:

order.orderdate.tostring()

"2009-10-17 11:22:46"

order.products.count

2order.customer.firstname

「order.customer.firstname」引發了「nhibernate.lazyinitializationexception」型別的異常

base :

entityid: 2

entityname: "model.entities.customer"

在上面的hql語句中通過fetch o.products語句來立即載入products,所以測試裡可以訪問products,而訪問customer時,則出錯了。

然後我們修改上面的hql語句:

"from order o left join fetch o.products where o.orderid=2 "

為如下"from order o left join fetch o.products inner join fetch o.customer where o.orderid=2 "

並再進行同上面一樣的測試看結果如何,我的如下:

order.orderdate.tostring()

"2009-10-17 11:22:46"

order.products.count

2order.customer.firstname

"soldier"

Hibernate 延遲載入和立即載入

概念 什麼是延遲載入 所謂延遲載入就是當在真正需要資料的時候,才真正執行資料載入操作。可以簡單理解為,只有在使用的時候,才會發出sql語句進行查詢,資料是分n次讀取。一 延遲載入 nhibernate延遲載入須有session存在,且配置為lazy true 預設 dal中編寫方法如下 延遲載入 p...

Hibernate 延遲載入和立即載入

延遲載入 延遲載入 lazy load懶載入 是當在真正需要資料時,才執行sql語句進行查詢,避免了無謂的效能開銷。延遲載入分類 01.類級別的查詢策略 02.一對多和多對多關聯的查詢策略 03.多對一關聯的查詢策略 如果程式載入乙個物件的目的是為了訪問它的屬性,可採取立即檢索,如果程式載入乙個持久...

hibernate延遲載入

在hibernate應用中,有時候只訪問指定的持久化物件,在載入該物件時沒有必要載入其關聯的物件,以免浪費記憶體空間,但若想在session關閉後正常訪問該物件,必須在載入該物件時,一起載入該物件的關聯物件,為了滿足檢索持久化物件的不同情況的需求,開發靈活高效的hibernate應用,hiberna...