延遲載入機制
阿新 • • 發佈:2018-12-17
延遲載入機制是為了避免一些無謂的效能開銷而提出來的,所謂延遲載入就是當在真正需要資料的時候,才真正執行資料載入操作。在Hibernate中提供了對實體物件的延遲載入以及對集合的延遲載入,另外在Hibernate3中還提供了對屬性的延遲載入。下面我們就分別介紹這些種類的延遲載入的細節。A、實體物件的延遲載入:如果想對實體物件使用延遲載入,必須要在實體的對映配置檔案中進行相應的配置,
如下所示: <hibernate-mapping><class name=”com.neusoft.entity.User” table=”user” lazy=”true”> ……</class></hibernate-mapping> 通過將class的lazy屬性設定為true,來開啟實體的延遲載入特性。
如果我們執行下面的程式碼:
User user=(User)session.load(User.class,”1”);
(1)System.out.println(user.getName());
(2)當執行到(1)處時,Hibernate並沒有發起對資料的查詢,如果我們此時通過一些除錯工具(比如JBuilder2005的Debug工具),觀察此時user物件的記憶體快照,我們會驚奇的發現,此時返回的可能是User$EnhancerByCGLIB$$bede8986型別的物件,而且其屬性為null,這是怎麼回事?還記得前面我曾講過session.load()方法,會返回實體物件的代理類物件,這裡所返回的物件型別就是User物件的代理類物件。在Hibernate中通過使用CGLIB,來實現動態構造一個目標物件的代理類物件,並且在代理類物件中包含目標物件的所有屬性和方法,而且所有屬性均被賦值為null。通過偵錯程式顯示的記憶體快照,我們可以看出此時真正的User物件,是包含在代理物件的CGLIB$CALBACK_0.target屬性中,當代碼執行到(2)處時,此時呼叫user.getName()方法,這時通過CGLIB賦予的回撥機制,實際上呼叫CGLIB$CALBACK_0.getName()方法,當呼叫該方法時,Hibernate會首先檢查CGLIB$CALBACK_0.target屬性是否為null,如果不為空,則呼叫目標物件的getName方法,如果為空,則會發起資料庫查詢,生成類似這樣的SQL語句:select * from user where id=’1’;來查詢資料,並構造目標物件,並且將它賦值到CGLIB$CALBACK_0.target屬性中。 這樣,通過一箇中間代理物件,Hibernate實現了實體的延遲載入,只有當用戶真正發起獲得實體物件屬性的動作時,才真正會發起資料庫查詢操作。所以實體的延遲載入是用通過中間代理類完成的,所以只有session.load()方法才會利用實體延遲載入,因為只有session.load()方法才會返回實體類的代理類物件。