hibernate懶加載


 Hibernate懶加載解析  hibernatejoinsession數據庫sqlobject Hibernate懶加載解析 在Hibernate框架中,當我們要訪問的數據量過大時,明顯用緩存不太合適, 因為內存容量有限 ,為了減少並發量,減少系統資源的消耗,這時Hibernate用懶加載機制來彌補這種缺陷,但是這只是彌補而不是用了懶加載總體性能就提高了。 我們所說的懶加載也被稱為延遲加載,它在查詢的時候不會立刻訪問數據庫,而是返回代理對象,當真正去使用對象的時候才會訪問數據庫。 實現懶加載的前提: 1 實體類不能是final的 2 能實現懶加載的對象都是被CGLIB(反射調用)改寫的代理對象,所以不能是final修飾的 3 須要asm,cglib兩個jar包 4 相應的lazy屬性為true 5 相應的fetch屬性為select 下面幾種可以實現懶加載功能: 1、 通過Session.load()實現懶加載 load(Object, Serializable):根據id查詢 。查詢返回的是代理對象,不會立刻訪問數據庫,是懶加載的。當真正去使用對象的時候才會訪問數據庫。 用load()的時候會發現不會打印出查詢語句,而使用get()的時候會打印出查詢語句。 使用load()時如果在session關閉之后再查詢此對象,會報異常:could not initialize proxy - no Session。處理辦法:在session關閉之前初始化一下查詢出來的對象:Hibernate.initialize(user); 使用load()可以提高效率,因為剛開始的時候並沒有查詢數據庫。但很少使用。 2、   one-to-one(元素)實現了懶加載。 在一對一的時候,查詢主對象時默認不是懶加載。即:查詢主對象的時候也會把從對象查詢出來。 需要把主對象配制成lazy="true" constrained="true"  fetch="select"。此時查詢主對象的時候就不會查詢從對象,從而實現了懶加載。 一對一的時候,查詢從對象的是默認是懶加載。即:查詢從對象的時候不會把主對象查詢出來。而是查詢出來的是主對象的代理對象。 3、   many-to-one(元素)實現了懶加載。 多對一的時候,查詢主對象時默認是懶加載。即:查詢主對象的時候不會把從對象查詢出來。 多對一的時候,查詢從對象時默認是懶加載。即:查詢從對象的時候不會把主對象查詢出來。 hibernate3.0中lazy有三個值,truefalse,proxy,默認的是lazy="proxy".具體設置成什么要看你的需求,並不是說哪個設置就是最好的。在<many-to-one>與<one-to-one>標簽上:當為true時,會有懶加載特性,當為false時會產生N+1問題,比如一個學生對應一個班級,用一條SQL查出10個學生,當訪問學生的班級屬性時Hibernate會再產生10條SQL分別查出每個學生對應的班級. lazy= 什么時候捉取 fetch= 捉取方式:select=關聯查詢;join=連接表的方式查詢(效率高) fetch=join時,lazy的設置將沒有意義. 4、   one-to-many(元素)懶加載:默認會懶加載,這是必須的,是重常用的。 一對多的時候,查詢主對象時默認是懶加載。即:查詢主對象的時候不會把從對象查詢出來。 一對多的時候,查詢從對象時默認是懶加載。即:查詢從對象的時候不會把主對象查詢出來。 需要配置主對象中的set集合lazy="false" 這樣就配置成是不懶加載了。或者配置抓取方式fetch="join"也可以變成不懶加載。 實現懶加載的方案: 方法一:(沒有使用懶加載) 用 Hibernate.initialize(de.getEmps()) 提前加載一下. 方法二: 把與Session脫離的對象重新綁定 lock()方法是用來讓應用程序把一個未修改的對象重新關聯到新session的方法。 //直接重新關聯
 session.lock(fritz,LockMode.NONE); //進行版本檢查后關聯
 session.lock(izi,LockMode.READ); //使用SELECT... FOR UPDATE進行版本檢查后關聯
 session.lock(pk,LockMode.UPGRADE); 方法三: OpenSessionInView 參見 http://www.javaeye.com/topic/32001 
 fetch 和 lazy 配置用於數據的查詢 lazy 參數值常見有 falsetrue,Hibernate3映射文件中默認lazy = true ; fetch 指定了關聯對象抓取的方式,參數值常見是select和join,默認是select,select方式先查詢主對象,再根據關聯外鍵,每一個對象發一個select查詢,獲取關聯的對象,形成了n+1次查詢;而join方式,是leftouter join查詢,主對象和關聯對象用一句外鍵關聯的sql同時查詢出來,不會形成多次查詢。 在映射文件中,不同的組合會使用不同的查詢: 1、lazy="true" fetch = "select" ,使用延遲策略,開始只查詢出主對象,關聯對象不會查詢,只有當用到的時候才會發出sql語句去查詢 ; 2、lazy="false" fetch = "select" ,沒有用延遲策略,同時查詢出主對象和關聯對象,產生1+n條sql. 3、lazy="true"或lazy="false"fetch = "join",延遲都不會作用,因為采用的是外連接查詢,同時把主對象和關聯對象都查詢出來了. 另 外,在hql查詢中,配置文件中設置的join方式是不起作用的,而在其他查詢方式如get、criteria等是有效的,使用 select方式;除非在hql中指定join fetch某個關聯對象。fetch策略用於get/load一個對象時,如何獲取非lazy的對象/集合。 這些參數在Query中無效。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM