什麼是Hibernate延時載入?
阿新 • • 發佈:2018-12-13
-
1、延遲載入,也叫懶載入,它是Hibernate為
提高程式執行效率
而提供的一種機制,即只有真正使用該物件的資料時才會建立。 -
2、Hibernate中主要是通過
代理(proxy)機制
來實現延遲載入。它的具體過程:Hibernate從資料庫獲取某一個物件資料時,或獲取某一個物件的集合屬性值時,或獲取某一個物件所關聯的另一個物件時,由於沒有使用到該物件的資料,hibernate並不從資料庫載入真正的資料,而只是為該物件建立一個代理物件來代表這個物件,這個物件上的所有屬性都是預設值;只有在真正需要使用該物件的資料時才建立這個真實物件,真正從資料庫中載入它的資料,這樣在某些情況下,就可以提高查詢效率。有如下程式程式碼:User user = (User) session.load(clazz, id); // 直接返回的是代理物件System.out.println(user.getId()); // 沒有傳送sql語句到資料庫載入user.getName(); // 建立真實的User例項,併發送sql語句到資料庫中 -
注意:
- 1、不能判斷User = null;代理物件不可能為空代理物件的限制:和代理關聯的session物件,如果session關閉後訪問代理則拋異常。session關閉之前訪問資料庫
- 2、getId()方法不行因為引數為ID,getClass()方法不用訪問資料庫就可以得到的資料
-
Hibernate中預設採用延遲載入的情況主要有以下幾種
- 1、當呼叫session上的load()載入一個實體時,會採用延遲載入。
- 2、當session載入某個實體時,會對這個實體中的集合屬性值採用延遲載入。
- 3、當session載入某個實體時,會對這個實體所有單端關聯的另一個實體物件採用延遲載入。
- 當實體中存在另一個實體物件的時候,延遲載入決定了抓取方式:當為Lazy載入時,在一個session中,如果不訪問實體中的實體物件屬性,hibernate就不會級聯查詢內部實體,當為EAGER的時候,hibernate會在查詢實體的時候,級聯查詢實體內部的其他實體物件。
- 延遲載入也稱為懶載入,
是Hibernate3關聯關係物件預設的載入方式
,所謂延遲載入就是當在真正需要資料的時候,才真正執行資料載入操作。簡單理解為,只有在使用的時候,才會發出sql語句進行查詢。 - 延遲載入的有效期是在session開啟的情況下,當session關閉後,會報異常。當呼叫load方法載入物件時,返回代理物件,等到真正用到物件的內容時才發出sql語句。
- 回顧事務:
- 事務:首先應該理解這個詞在SQL裡面是什麼意思。
- 事務:就是一組簡單的邏輯單元,事務的四個特性:原子性、一致性、隔離性、永續性。
- 事務的分類:顯示、隱式、自動提交。
- 事務的建立:開始事務:begin transcation
- 提交事務:commit transaction
- 回滾事務:rollback transaction
- 非延遲載入在讀取一個物件的時候會將與這個物件所有相關的其他物件一起讀取出來。
- Hibernate提供的延遲載入機制。這種初始化策略只在一個物件呼叫它的一對多或多對多關係時才將關係物件讀取出來。
- 這個過程對開發者來說
是透明的
,而且只進行了很少的資料庫操作請求
,因此會得到比較明顯的效能提升
。這項技術的一個缺陷是延遲載入技術要求一個Hibernate會話要在物件使用的時候一直開著
。
- 提高效率,主要是對屬性(在資料庫中存在相應的表)進行延遲載入(load),在第一次查詢的時候,只查詢當前的表,當用到延遲載入的物件時(非延遲載入會查詢所有關聯屬性的表),會先從快取中去找延遲載入的物件(如果session已經關閉,會丟擲SessionClosedException),如果物件已經在快取中,則直接從快取獲取,如果物件不在快取中,則進入資料庫查詢,所以,延遲載入是為了提高效率,如果在hibernate對映檔案lazy設定成false,用load則和用get效果一樣。
- 延時載入是指:不是一開始就建立物件,而是當要呼叫的時候才去建立物件。
- 延時載入不是問題,是為了解決問題,在hibernate中,有兩種關係是相對存在的,就是一對多和多對一,如果同時使用這兩種關係,並且不使用延遲載入會很麻煩的。
- 比如:學生和班級的關係。
- 學生實體裡應該存在一個班級實體,班級實體裡應該存在學生集合。
- 如果使用急切載入,那麼在查詢學生的時候需要查出班級,而班級又需要查詢學生集合,而每個學生又需要班級實體……如此反覆,直到記憶體崩潰。
- 而是用延遲載入,在查詢學生時,不需要直接載入班級,在查詢班級時也不需要學生集合,他們都是在需要的時候才去查詢,很好得解決了死迴圈的問題。