近段時間在讀孫維琴的《精通hibernate》,感覺收獲不少,對于hibernate檢索策略的第一部分,感覺其實就是幾張表,如果把幾張表搞清楚了,其他的也就無所謂了,幸而書中總結的很好,就摘錄如下:
注意:此版本主要是基于hibernate2.x版本。
類級別和關聯級別可選的檢索策略和默認的檢索策略
檢索策略的作用域 |
可選的檢索策略 |
默認的檢索策略 |
運行時行為受影響的sesssion的檢索方法 |
類級別 |
立即檢索
延遲檢索 |
立即檢索 |
僅影響load()方法 |
關聯級別 |
立即檢索
延遲檢索
迫切左外連接檢索 |
多對一和一對一關聯為外連接檢索 |
影響load(),get(),find()方法 |
一對多和多對多關聯為立即檢索 |
三種檢索策略的運行機制
檢索策略的類型 |
類級別 |
關聯級別 |
優點 |
缺點 |
優先考慮使用的場合 |
立即檢索 |
立即加載檢索方法指定的對象 |
立即加載與檢索方法指定的對象關聯的對象,可以設定批量檢索數量 |
對應用程序完全透明,不管對象處于持久化狀態,還是游離狀態,應用程序都可以方便地從一個對象導航到與它關聯的對象 |
(1)select語句數目多;(2)可能會加載應用程序不需要訪問的對象,造成內存空間的浪費 |
(1)類級別(2)應用程序需要立即訪問的對象(3)使用了二級緩存 |
延遲檢索 |
延遲加載檢索方法指定的對象 |
延遲加載與檢索方法指定的對象,可以設定批量檢索數量 |
由應用程序決定需要加載那些對象,可以避免執行多余的select語句,以及避免加載應用程序不需要訪問的對象。因此提高檢索性能,并能節省內存空間 |
應用程序如果希望訪問游離狀態的代理類實例,必須保證它在持久化狀態時已經被初始化 |
(1)一對多或多對多關聯(2)應用程序不需要立即訪問或者根本不會訪問的對象 |
迫切左外連接檢索 |
不適用 |
通過左外連接加載與檢索方法指定的對象 |
(1)對應用程序完全透明,不管對象處于持久化狀態,還是游離狀態,應用程序都可以方便地從一個對象導航到與它關聯的對象(2)使用了外連接,select語句數目少 |
(1)可能會加載應用程序不需要訪問的對象,造成內存空間的浪費(2)復雜的數據表連接也會影響檢索性能 |
(1)多對一或一對一關聯(2)應用程序需要立即訪問的對象(3)數據庫系統具有良好的表連接性能 |
映射文件中用于設定檢索策略的幾個屬性
屬性 |
可選值 |
默認值 |
描述 |
lazy |
true或false |
hibernate2.x版本為false
hibernate3.x版本為true |
如果為true,表示使用延遲策略。在<class>和<set>中包含此屬性 |
outer-join |
auto、true或false |
在<many-to-one>和<one-to-one>元素中為auto;在<set>元素中為false |
如果為true,表示使用迫切左外連接檢索。在<many-to-one>、<one-to-one>和<set>元素中包含此屬性 |
batch-size |
正整數 |
1 |
設定批量檢索的數量。如果設定此項,合理的取值在3~10之間。僅適用于關聯級別的立即檢索和延遲檢索,在<class>和<set>元素中包含此屬性 |
Set元素的lazy和outer-join屬性
lazy屬性 |
outer-join屬性 |
檢索策略 |
false |
true |
采用立即檢索,這是默認的檢索策略,當使用hibernate二級緩存可以考慮使用立即檢索 |
false |
false |
采用迫切左外連接檢索。對于hibernate2.x版本,在映射文件中如果有多個<set>元素,只允許有一個<set>元素的outer-join屬性為true |
true |
false |
采用延遲檢索。這是優先考慮的檢索策略 |
true |
true |
沒有任何意義 |
設置多對一關聯的檢索策略
(以客戶和訂單為例)
Order.hbm.xml的<many-to-one>元素的outer-join屬性 |
Customer.hbm.xml的<calss>元素的lazy屬性 |
檢索order對象時,對關聯的customer對象使用的檢索策略 |
auto |
true |
延遲檢索 |
auto |
false |
迫切左外連接檢索 |
true |
true |
迫切左外連接檢索 |
true |
false |
迫切左外連接檢索 |
false |
true |
延遲檢索 |
false |
false |
立即檢索 |
注:
1默認情況下,Hibernate 3對集合使用延遲select抓取,對返回單值的關聯使用延遲代理抓取。
2在Hibernate2.1中,lazy屬性的默認值為“false”,而在Hibernate3.0中,lazy屬性的默認值為“true”。
3FetchMode.LAZY 和 FetchMode.EAGER被廢棄。取而代之的分別為FetchMode.SELECT 和FetchMode.JOIN。