1. 程式人生 > >hibernate懶載入的原理和作用

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先預設使用延遲載入,而後又必須去資料庫載入,反而會降低效率

  1. 載入單個實體,如果不需要延遲載入,就可以使用session的get()方法。

  2. 當session載入某個實體時,不需要對這個實體中的集合屬性值延遲載入,而是要立即載入。這是可以在對映檔案中這個集合的配置元素(set bag list)新增屬性lazy=false;

  3. 當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)