Hibernate延遲加載實現原理

通過將class的lazy屬性設置爲true,來開啓實體的延遲加載特性。
如果我們運行下面的代碼:
User user=(User)session.load(User.class,"1");(1)   
System.out.println(user.getName());                 (2) 
當運行到(1)處時,Hibernate並沒有發起對數據的查詢,如果我們此時通過一些調試工具(比如Eclipse的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()方法纔會返回實體類的代理類對象。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章