Hibernate的延遲加載(lazy load)是一個被廣泛使用的技術。這種延遲加載保證了應用只有在需要時纔去數據庫
中抓取相應的記錄。通過延遲加載技術可以避免過多、過早地加載數據表裏的數據,從而降低應用的內存開銷。如果
在獲取對象的時候使用的是session.get()是不會延遲加載的,只有在使用load、hql時候纔會延遲加載。我們簡單介紹一
下hibernate中的lazy策略。
lazy策略可以用在:
1、 <class>標籤上:可以取值true/false
1. <property>標籤上,可以取值true/false,這個特性需要類增強(不常用)
2. 設置<class>標籤中的lazy="true",或是保持默認(即不配置lazy屬性)
3. 如果lazy的屬性值爲true,那麼在使用load方法加載數據時,只有確實用到數據的時候纔會發出sql語句;這樣
有可能減少系統的開銷。
注:<class>上的lazy隻影響普通屬性
2、集合(collection)的延遲加載。
主要應用在<set>/<list>等集合上:可以取值true,false,extra (常用extra,比較智能)。
1. true:默認取值,它的意思是只有在調用這個集合獲取裏面的元素對象時,才發出查詢語句,加載其集合元素的
數據。
2.false:取消延時加載特性,即在加載對象的同時,就發出第二條查詢語句加載其關聯集合的數據
3. extra:一種比較聰明的懶加載策略,即調用集合的size/contains等方法的時候,hibernate並不會去加載整個集合
的數據,而是發出一條聰明的SQL語句,以便獲得需要的值,只有在真正需要用到這些集合元素對象數據的時
候,才去發出查詢語句加載所有對象的數據
3、單端關聯延遲加載策略。
配置在<one-to-one>/<many-to-one>等標籤上,可以取值false/proxy/no-proxy
1. false:取消遲加加載策略,即在加載對象的同時,發出查詢語句,加載其關聯對象
2. proxy(默認):這是hibernate對單端關聯的默認懶加載策略,即只有在調用到其關聯對象的方法的時候才真正
發出查詢語句查詢其對象數據,其關聯對象是代理類
3. no-proxy:這種懶加載特性需要對類進行增強,使用no-proxy,其關聯對象不是代理類
注:
1、load默認會開啓延遲加載,而get不支持延遲加載。
2、當查詢特定的數據庫中不存在的數據時,get會返回null,而load則拋出異常。
理解:
1. Hibernate的延遲加載本質上就是代理模式的應用,當程序通過 Hibernate裝載一個實體時,默認情況
下,Hibernate並不會立即抓取它的集合屬性、關聯實體所以對應的記錄,而是通過生成一個代理來表示這些集合屬
性、關聯實體,這就是代理模式應用帶來的優勢。
2. 延遲加載也是項目開發中特別常見的一個錯誤。如果對一個類或者集合配置了延遲檢索策略,那麼必須當代理
類實例或代理集合處於持久化狀態(即處於Session範圍內)時,才能初始化它。如果在遊離狀態時才初始化它,就會
產生延遲初始化錯誤。所以,在開發獨立的DAO數據訪問層時應該格外小心這個問題。
3. 延遲加載是一個非常有用的策略,但是有時候也會影響性能,例如:如果我們確定某個對象的關聯對象會被使
用,乾脆一次都加載上來,比延遲加載性能要好些。總之使用lazy要根據實際需求,這也是爲什麼hibernate設置lazy
有不同屬性的原因。