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有三個值,true,false,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 參數值常見有 false 和 true,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中無效。
版權聲明:本文爲博主原創文章,未經博主容許不得轉載。java