1. 程式人生 > >get、load與懶載入小總結

get、load與懶載入小總結

一、get()與load()

1、 是否支援懶載入

Load支援懶載入,get不支援懶載入

2、 載入時機不同

Load採用延遲載入,等到使用非主鍵時才去讀庫

Get馬上讀庫

3、 搜素不到資料時的情況

當搜素的資料不存在時,load會返回一個物件,在使用該物件的非主鍵屬性時會丟擲一個ObjectNotFoundException。 

當搜素的資料不存在時,get會返回null;

【為什麼只有在使用該物件的非主鍵屬性時才會拋異常?

Users user = (Users)session.load(Users.class, userId);  

System.out.println(user.getId());  

上面這2句程式碼,不會去執行資料庫操作。因為load後會在hibernate的一級快取裡存放一個map物件,該map的key就是userId的值,但是當你getId()時,它會去一級快取裡拿map的key值,而不去執行資料庫查詢。所以不會報任何錯。不會執行任何資料庫操作。

get和load的根本區別,一句話,hibernate對於load方法認為該資料在資料庫中一定存在,可以放心的使用代理來延遲載入,如果在使用過程中發現了問題,只能拋異常;而對於get方法,hibernate一定要獲取到真實的資料,否則返回null。

注意:get方法如果在session快取中找到了該id對應的物件,如果剛好該物件前面是被代理過的,如被load方法使用 過,或者被其他關聯物件延遲載入過,那麼返回的還是原先的代理物件,而不是實體類物件,如果該代理物件還沒有載入實體資料(就是id以外的其他屬性數 據),那麼它會查詢二級快取或者資料庫來載入資料,但是返回的還是代理物件,只不過已經載入了實體資料

二、lazy的概念和策略

Lazy的概念:

只有在真正使用該物件時,才會建立,對hibernate而言,真正使用的時候才會發出

Hibernate支援lazy只有在session開啟的狀態下才有效

在<class>上lazy為true時,load不發出sql語句,只有使用時才發出;為false時在第一次load時就執行全部sql語句;為extra時和true差不多,不過發出的sql語句比較智慧【集合標籤上面的lazy特性推薦使用extra】

Hibernate lazy策略的可以使用在:

1、<class>標籤,取值可以為true、false【只對普通屬性起作用,不會影響集合和單端上面的lazy屬性】

2、<property>標籤上,取值可以為true、false(需要增強類)

3、<set><list>上的取值可以為false、true和extra

4、<one-to-one>、<many-to-one>單端關聯上,取值可以為false/true/noproxy