天天看點

Hibernate中Session.load與Session.get的差別

Session.load/get方法均可以根據指定的實體類和id從資料庫讀取記錄,并傳回與之對應的實體對象。其差別在于:

如果未能發現符合條件的記錄,get方法傳回null,而load方法會抛出一個ObjectNotFoundException。

Load方法可傳回實體的代理類執行個體,而get方法永遠直接傳回實體類。

load方法可以充分利用内部緩存和二級緩存中的現有資料,而get方法則僅僅在内部緩存中進行資料查找,如沒有發現對應資料,将越過二級緩存,直接調用SQL完成資料讀取。

Session在加載實體對象時,将經過的過程:

首先,Hibernate中維持了兩級緩存。第一級緩存由Session執行個體維護,其中保持了Session目前所有關聯實體的資料,也稱為内部緩存。而第二級緩存則存在于SessionFactory層次,由目前所有由本SessionFactory構造的Session執行個體共享。出于性能考慮,避免無謂的資料庫通路,Session在調用資料庫查詢功能之前,會先在緩存中進行查詢。首先在第一級緩存中,通過實體類型和id進行查找,如果第一級緩存查找命中,且資料狀态合法,則直接傳回。

之後,Session會在目前“NonExists”記錄中進行查找,如果“NonExists”記錄中存在同樣的查詢條件,則傳回null。“NonExists”記錄了目前Session執行個體在之前所有查詢操作中,未能查詢到有效資料的查詢條件(相當于一個查詢黑名單清單)。如此一來,如果Session中一個無效的查詢條件重複出現,即可迅速作出判斷,進而獲得最佳的性能表現。

對于load方法而言,如果内部緩存中未發現有效資料,則查詢第二級緩存,如果第二級緩存命中,則傳回。

如在緩存中未發現有效資料,則發起資料庫查詢操作(Select SQL),如經過查詢未發現對應記錄,則将此次查詢的資訊在“NonExists”中加以記錄,并傳回null。

根據映射配置和Select SQL得到的ResultSet,建立對應的資料對象。

将其資料對象納入目前Session實體管理容器(一級緩存)。

執行Interceptor.onLoad方法(如果有對應的Interceptor)。

将資料對象納入二級緩存。

如果資料對象實作了LifeCycle接口,則調用資料對象的onLoad方法。

傳回資料對象

文章出處:飛諾網(

www.firnow.com):http://dev.firnow.com/course/3_program/java/javajs/20090215/155632.html