標籤:工具 font 程式 png 異常 代理類 子查詢 指定 使用
不浪費記憶體:當 Hibernate 從資料庫中載入 Customer 對象時, 如果同時載入所有關聯的 Order 對象, 而程式實際上僅僅需要訪問 Customer 對象, 那麼這些關聯的 Order 對象就白白浪費了許多記憶體.
更高的查詢效率:發送儘可能少的 SQL 陳述式
類層級的檢索策略
1.類層級可選的檢索策略包括立即檢索和延遲檢索, 預設為延遲檢索
立即檢索: 立即載入檢索方法指定的對象
延遲檢索: 消極式載入檢索方法指定的對象。在使用具體的屬性時,再進行載入
2.類層級的檢索策略可以通過 <class> 元素的 lazy 屬性進行設定
3.如果程式載入一個對象的目的是為了訪問它的屬性, 可以採取立即檢索.
4.如果程式載入一個持久化對象的目的是僅僅為了獲得它的引用, 可以採用延遲檢索。注意出現懶載入異常!
5.無論 <class> 元素的 lazy 屬性是 true 還是 false, Session 的 get() 方法及 Query 的 list() 方法在類層級總是使用立即檢索策略
6.若 <class> 元素的 lazy 屬性為 true 或取預設值, Session 的 load() 方法不會執行查詢資料表的 SELECT 語句, 僅返回代理類對象的執行個體, 該代理類執行個體有如下特徵:
(1)由 Hibernate 在運行時採用 CGLIB 工具動態產生
(2)Hibernate 建立代理類執行個體時, 僅初始化其 OID 屬性
(3)在應用程式第一次訪問代理類執行個體的非 OID 屬性時, Hibernate 會初始化代理類執行個體
一對多和多對多的檢索策略
在對應檔中, 用 <set> 元素來配置一對多關聯及多對多關聯關係. <set> 元素有 lazy 和 fetch 屬性
(1)lazy: 主要決定 orders 集合被初始化的時機. 即到底是在載入 Customer 對象時就被初始化, 還是在程式訪問 orders 集合時被初始化
(2)fetch: 取值為 “select” 或 “subselect” 時, 決定初始化 orders 的查詢語句的形式; 若取值為”join”, 則決定 orders 集合被初始化的時機
(3)若把 fetch 設定為 “join”, lazy 屬性將被忽略
(4)<set> 元素的 batch-size 屬性:用來為延遲檢索策略或立即檢索策略設定批量檢索的數量. 批量檢索能減少 SELECT 語句的數目, 提高延遲檢索或立即檢索的運行效能.
<set> 元素的 lazy 和 fetch 屬性
延遲檢索和增強延遲檢索
在延遲檢索(lazy 屬性值為 true) 集合屬性時, Hibernate 在以下情況下初始化集合代理類執行個體
(1)應用程式第一次訪問集合屬性: iterator(), size(), isEmpty(), contains() 等方法
(2)通過 Hibernate.initialize() 靜態方法顯式初始化
增強延遲檢索(lazy 屬性為 extra): 與 lazy=“true” 類似. 主要區別是增強延遲檢索策略能進一步延遲 Customer 對象的 orders 集合代理執行個體的初始化時機:
(1)當程式第一次訪問 orders 屬性的 iterator() 方法時, 會導致 orders 集合代理類執行個體的初始化
(2)當程式第一次訪問 order 屬性的 size(), contains() 和 isEmpty() 方法時, Hibernate 不會初始化 orders 集合類的執行個體, 僅通過特定的 select 語句查詢必要的資訊, 不會檢索所有的 Order 對象
用帶子查詢的 select 語句整批量初始化 orders 集合(fetch 屬性為 “subselect”)
<set> 元素的 fetch 屬性: 取值為 “select” 或 “subselect” 時, 決定初始化 orders 的查詢語句的形式; 若取值為”join”, 則決定 orders 集合被初始化的時機.預設值為 select
當 fetch 屬性為 “subselect” 時:
(1)假定 Session 緩衝中有 n 個 orders 集合代理類執行個體沒有被初始化, Hibernate 能夠通過帶子查詢的 select 語句, 來批量初始化 n 個 orders 集合代理類執行個體
(2)batch-size 屬性將被忽略
(3)子查詢中的 select 語句為查詢 CUSTOMERS 表 OID 的 SELECT 語句
迫切左外串連檢索(fetch 屬性值設為 “join”)
<set> 元素的 fetch 屬性: 取值為 “select” 或 “subselect” 時, 決定初始化 orders 的查詢語句的形式; 若取值為”join”, 則決定 orders 集合被初始化的時機.預設值為 select
當 fetch 屬性為 “join” 時:
(1)檢索 Customer 對象時, 會採用迫切左外串連(通過左外串連載入與檢索指定的對象關聯的對象)策略來檢索所有關聯的 Order 對象
(2)lazy 屬性將被忽略
(3)Query 的list() 方法會忽略對應檔中配置的迫切左外串連檢索策略, 而依舊採用消極式載入策略
多對一和一對一關聯的檢索策略
和 <set> 一樣, <many-to-one> 元素也有一個 lazy 屬性和 fetch 屬性.
若 fetch 屬性設為 join, 那麼 lazy 屬性被忽略
迫切左外串連檢索策略的優點在於比立即檢索策略使用的 SELECT 語句更少.
無代理延遲檢索需要增強持久化類的位元組碼才能實現
Query 的 list 方法會忽略對應檔配置的迫切左外串連檢索策略, 而採用延遲檢索策略
如果在關聯層級使用了消極式載入或立即載入檢索策略, 可以設定批量檢索的大小, 以協助提高延遲檢索或立即檢索的運行效能.
Hibernate 允許在應用程式中覆蓋對應檔中設定的檢索策略.
總結
類層級和關聯層級可選的檢索策略及預設的檢索策略
3 種檢索策略的運行機制
對應檔中用於設定檢索策略的幾個屬性
比較 Hibernate 的三種檢索策略
Hibernate的檢索策略