hibernate懶載入的原理和作用
一.什麼是懶載入?他的作用?
延遲載入,也叫懶載入,它是hibernate為提高程式執行效率而提供的一種機制,即只有真正使用該物件的資料時才會建立。
Hibernate中主要是通過代理(proxy)機制來實現延遲載入。它的具體過程:Hibernate從資料庫獲取某一個物件資料時、獲取某一個物件的集合屬性值時,或獲取某一個物件所關聯的另一個物件時,由於沒有使用該物件的資料,hibernate並不是資料庫載入真正的資料,而只是為該物件建立一個代理物件來代表這個物件,這個物件上的所有屬性都是預設值;只有在真正需要使用該物件的資料時才建立這個真實物件,真正從資料庫中載入它的資料,這樣在某些情況下,就可以提高查詢效率。
有如下程式程式碼:
User user=(User)session.load(clazz, id);//直接返回的是代理物件
System.out.println(user.getId());//沒有傳送sql語句到資料庫載入
user.getName();//建立真實的User例項,併發送sql語句到資料庫中
- 1
- 2
- 3
- 4
- 5
注意:1.不能判斷user=null;代理物件不可能為空
代理物件的限制:和代理關聯的session物件,如果session關閉後訪問代理則拋異常。session關閉之前訪問資料庫
2.getId()方法不行因為引數為ID,getClass()方法不用訪問資料庫就可以得到的資料
Hibernate中預設採用延遲載入的情況主要有以下幾種
1,當呼叫session上的load()載入一個實體時,會採用延遲載入。
2,當session載入某個實體時,會對這個實體中的集合屬性值採用延遲載入
3,當session載入某個實體時,會對這個實體所有單端關聯的另一個實體物件採用延遲載入。
二.關閉延遲載入
延遲載入確實會給程式的查詢效率帶來好處,但有時明確知道資料需要立即載入,如果Hibernate先預設使用延遲載入,而後又必須去資料庫載入,反而會降低效率
-
載入單個實體,如果不需要延遲載入,就可以使用session的get()方法。
-
當session載入某個實體時,不需要對這個實體中的集合屬性值延遲載入,而是要立即載入。這是可以在對映檔案中這個集合的配置元素(set bag list)新增屬性lazy=false;
-
當session載入某個實體時,不需要對這個實體所單端關聯的另一個實體物件延遲載入,就可以在影射檔案中針對這個單端關聯的配置元素()新增lazy=false;
三.抓取策略
通過asm和cglib二個包實現;Domain是非final的。
1.session.load懶載入。
2.one-to-one(元素)懶載入:
必需同時滿足下面三個條件時才能實現懶載入
2) (主表不能有constrained=true,所以主表沒有懶載入)
lazy!=false
2)constrained=true
3)fetch=select
3.one-to-many (元素)懶載入:
1)lazy!=false
2)fetch=select
4.many-to-one (元素) :
1. lazy!=false
2)fetch=select
5.many-to-many (元素) :
1)lazy!=false
2)fetch=select
6.能夠懶載入的物件都是被改寫過的代理物件,當相關聯的session沒有關閉時,訪問這些懶載入物件(代理物件)的屬性(getId和getClass除外)hibernate會初始化這些代理,或用Hibernate.initialize(proxy)來初始化代理物件;當相關聯的session關閉後,再訪問懶載入的物件將出現異常。
Annotations | Lazy | Fetch |
---|---|---|
@[One|Many]ToOne](fetch=FetchType.LAZY) | @LazyToOne(PROXY) | @Fetch(SELECT) |
@[One|Many]ToOne](fetch=FetchType.EAGER) | @LazyToOne(FALSE) | @Fetch(JOIN) |
@LazyCollection(TRUE) | @Fetch(SELECT) | |
@LazyCollection(FALSE) | @Fetch(JOIN) |