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