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(元素)懶加載:
懶加載默認是關閉的,只有基于外鍵關聯方式的“一對一”才用懶加載。必需同時滿足下面三個條件時才能實現懶加載
(主表不能有constrained=true,所以主表沒有懶加載)
lazy!=false 2)constrained=true 3)fetch=select
3、one-to-many (元素)懶加載:
當我們查詢的是主對象時,將person和idcard外連接查詢出person對象和idcard對象沒有懶加載。當我們查詢的是從對象時,對于idcard所關聯的person對象是懶加載。
這種關聯方實質性懶加載是非常有效的,Hibernate默認對它就是使用懶加載的,默認就是以下條件:
1)lazy!=false 2)fetch=select
4、 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的設置將沒有意義.
.5、many-to-many (元素) :
這種關聯方實質性懶加載是非常有效的,Hibernate默認對它就是使用懶加載的,默認就是以下條件:
1)lazy!=false 2)fetch=select
6、.能夠懶加載的對象都是被改寫過的代理對象,當相關聯的session沒有關閉時,訪問這些懶加載對象(代理對象)的屬性(getId和getClass除外)hibernate會初始化這些代理,或用Hibernate.initialize(proxy)來初始化代理對象;當相關聯的session關閉后,再訪問懶加載的對象將出現異常。
7、抓取策略
a)??????? select:作為默認值,它的策略是當需要使用到關聯對象的數據時另外單獨發送select語句,抓取當前對象的關聯對象的數據。即懶加載。
b)??????? join:他的策略時使用一條select語句用內連接來獲取對象的數據和關聯對象的數據,此時關聯對象的懶加載失效。
除了上面說的在映射文件中配置,lazy=false之外,我們還可以通過以下方式來解決懶加載問題。
1.明確初始化:
在session還沒有關閉時,訪問一次xxxx.getXxx(),強制訪問數據庫。或者Hibernate.initialize(xxx)
2.openSessionView ? 這個往往需要過濾器配合使用
3.在ssh中,可以實現在service層,標注方式來解決懶加載。
本文地址:http://www.blogfshare.com/hibernate-lazy.html
總結
以上是生活随笔為你收集整理的Hibernate懒加载的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hibernate 对象的三种状态
- 下一篇: Struts2内置拦截器和自定义拦截器