<a href="http://www.cnblogs.com/wolf-sun/p/4077226.html#t1" target="_blank">寫在前面</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4077226.html#t2" target="_blank">文檔與系列文章</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4077226.html#t3" target="_blank">延遲加載</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4077226.html#t4" target="_blank">一個例子</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4077226.html#t5" target="_blank">總結</a>
上篇文章介紹了多對多關系的關聯查詢的sql,hql,criteria查詢的三種方式。本篇文章将介紹nhibernate中的延遲加載方式,延遲加載按個人了解也可以叫做按需要加載(loading-on-demand)。
<a href="http://www.cnblogs.com/wolf-sun/p/3694592.html">[nhibernate]體系結構</a>
<a href="http://www.cnblogs.com/wolf-sun/p/3694901.html">[nhibernate]isessionfactory配置</a>
<a href="http://www.cnblogs.com/wolf-sun/p/3704012.html">[nhibernate]持久化類(persistent classes)</a>
<a href="http://www.cnblogs.com/wolf-sun/p/3705229.html">[nhibernate]o/r mapping基礎</a>
<a href="http://www.cnblogs.com/wolf-sun/p/3720259.html">[nhibernate]關聯映射</a>
<a href="http://www.cnblogs.com/wolf-sun/p/3721528.html">[nhibernate]parent/child</a>
<a href="http://www.cnblogs.com/wolf-sun/p/3724052.html">[nhibernate]緩存(nhibernate.caches)</a>
<a href="http://www.cnblogs.com/wolf-sun/p/3734249.html">[nhibernate]nhibernate.tool.hbm2net</a>
<a href="http://www.cnblogs.com/wolf-sun/p/3734313.html">[nhibernate]nullables</a>
<a href="http://www.cnblogs.com/wolf-sun/p/3956802.html">[nhibernate]nhibernate如何映射sqlserver中image字段</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4046672.html">[nhibernate]條件查詢criteria query</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4048048.html">[nhibernate]增删改操作</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4049716.html">[nhibernate]事務</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4050714.html">[nhibernate]并發控制</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4067026.html">[nhibernate]元件之依賴對象</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4068749.html">[nhibernate]一對多關系(級聯删除,級聯添加)</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4070935.html">[nhibernate]一對多關系(關聯查詢)</a>
<a href="http://www.cnblogs.com/wolf-sun/p/4074654.html">[nhibernate]多對多關系(關聯查詢)</a>
延遲加載(lazy load)是(也成為懶加載)hibernate3關聯關系對象預設的加載方式,延遲加載機制是為了避免一些無謂的性能開銷而提出來的,所謂延遲加載就是當在真正需要資料的時候,才真正執行資料加載操作。可以簡單了解為,隻有在使用的時候,才會發出sql語句進行查詢。 延遲加載的有效期是在session打開的情況下,當session關閉後,會報異常。當調用load方法加載對象時,傳回代理對象,等到真正用到對象的内容時才發出sql語句。 hibernate2實作延遲加載有2種方式:1實體對象,2集合。 hibernate3中又引入了一種新的加載方式:3屬性的延遲加載。 一般使用load的方法來實作延遲加載,在實作無限級關聯使用延遲加載效率比較好。 ——百度百科(java,hibernate)
上面是java中對hibernate的延遲加載的描述,說的比我好多了。
記住三點:1,為了避免無謂的性能開銷。2,需要時才真正加載資料。3,使用了代理。
預設延遲加載
采用懶加載的方式根據客戶id得到客戶資訊


測試用代碼,如圖所示,此時資料已經加載出來了
使用sql profile監控生成的sql語句,截圖如下
你會發現,此時隻生成了查詢customer的sql語句,nhibernate預設是使用延遲加載的,在前面的文章中,并沒在映射檔案中設定節點的lazy屬性。
當展開customer的屬性orders時或者調試向下移動的時候,會執行查詢,你會看到如下的sql語句
延遲加載并關閉session


測試,當視圖展開customer的orders屬性,或者往下執行獲得order集合時出錯。
延遲加載,需要的時候再去加載,因為此時session已經關閉,沒有去查詢的通道了,結果是“此路不通”的提示。
這裡采用多對多關系那篇文章中舉的 order和product的例子。


進行測試,在查詢的時候隻有order表的資料(這個地方,有order資料的sql,猜測在一對多查詢的時候,沒有出現查詢customer的sql語句,很有可能是因為緩存的問題造成,因為經常使用cusomer那條資料進行測試。)
展開order的屬性
當展開order的屬性,回去查詢order下的所有的product,此時生成的sql如下:


測試
此時生成的sql語句
如果此時展開products,同樣會出現上面的異常
通過上面的比較一對多和多對多的預設延遲加載和關閉session後的情況類似。
n+1次select查詢問題
如果order下有很多個product,而我們就想需要的時候才去加載其中某些product的資訊,如果采用立即加載的方式,勢必産生多個sql語句,例如第一次查詢得到所有的order對象,然後根據orderid去查詢得到所有的産品。
測試,多對多延遲加載訂單和訂單下單價大于6666的産品


生成的sql語句
延遲加載,可以解決select n+1的問題,比如你查詢一個訂單還有訂單下的product,勢必會産生多條sql語句,先是查詢order的sql語句,然後是查詢product的sql語句,就會頻繁的查詢資料庫,造成性能方面的壓力,而采用延遲加載,通過上面生成的sql語句你會發現,使用left out join 将關聯的表拼接起來,隻生成了一條sql。
本篇文章介紹了nhibernate在延遲加載方面的内容,nhibernate在使用過程中延遲加載方式是預設的。對延遲加載的定義,需要再慢慢的體會。
部落格位址:
<a href="http://www.cnblogs.com/wolf-sun">http://www.cnblogs.com/wolf-sun/</a>
部落格版權:
本文以學習、研究和分享為主,歡迎轉載,但必須在文章頁面明顯位置給出原文連接配接。
如果文中有不妥或者錯誤的地方還望高手的你指出,以免誤人子弟。如果覺得本文對你有所幫助不如【推薦】一下!如果你有更好的建議,不如留言一起讨論,共同進步!
再次感謝您耐心的讀完本篇文章。
轉載:http://www.cnblogs.com/wolf-sun/p/4077226.html