Hibernate之检索策略
1.概述
檢索數據時的2個問題:
-
不浪費內存:當Hibernate從數據庫中加載Customer對象時,如果同時加載所有關聯的Order對象,而程序僅僅需要訪問Customer對象,那么關聯的Order對象就白白浪費了許多內存
-
更高的查詢效率:發送盡可能少的SQL語句
2.類級別的檢索策略
-
包括立即檢索和延遲檢索,默認為延遲檢索
-
立即檢索:立即加載檢索方法指定的對象
-
延遲檢索:延遲加載檢索方法指定的對象
-
-
類級別的檢索策略可以通過<class>元素的lazy屬性進行設置
-
如果程序加載一個對象的目的是為了訪問它的屬性,可以采取立即檢索
-
如果僅僅是為了獲得它的引用,可以采用延遲索引
-
-
無論<class>元素的lazy屬性是true還是false,Session的get()方法和Query的list()方法在類級別總是使用立即檢索策略
3.一對一和多對多的檢索策略
-
在映射文件中,用<set>元素來配置一對多關聯及多對多管理關系。<set>元素有lazy和fetch屬性
-
lazy:主要決定orders集合被初始化的實際
-
fetch:取值為“select”或“subselect”時,決定初始化orders的查詢語句的形式;若取值為“join”,則決定orders集合被初始化的時機
-
若把fetch設置為“join”,lazy屬性將被忽略
-
<set>元素的batch-size屬性:用來為延遲檢索策略或理解檢索策略設定批量檢索的數量
-
| true | select | 延遲檢索 |
| false | select | 立即檢索 |
| extra | select | 加強延遲檢索 |
| true,false或extra | select | select查詢:select * from orders where customer_id in(1,2,3,4) |
| true,false或extra | subselect | 子查詢:select * from orders where customer_id in(select id from customers) |
| true | join | 采用迫切左外連接策略 |
(1)延遲檢索
-
Hibernate在以下情況下初始化集合代理類實例
-
應用程序第一次訪問集合屬性,iterator(),size(),isEmpty(),contains()等方法
-
通過Hibernate.initialize()靜態方法顯式初始化
-
(2)增強延遲檢索
-
進一步延遲Customer對象的Orders集合代理實例的初始化時機
-
當程序第一次訪問orders屬性的iterator()方法,會導致orders集合代理類實例的初始化
-
當程序第一次訪問order屬性的size(),contains()和isEmpty()方法時,Hibernate不會初始化orders集合類的實例,僅通過特定的select語句查詢必要的信息。比如:select count(*) from order where 條件
-
(3)<set>元素的batch-size屬性
<set> 元素有一個 batch-size 屬性, 用來為延遲檢索策略或立即檢索策略設定批量檢索的數量. 批量檢索能減少 SELECT 語句的數目, 提高延遲檢索或立即檢索的運行性能
若batch-size設置為3,有5條數據 select * from order where customer_id in(1,2,3) select * from order where customer_id in(4,5)(4)迫切左外連接
-
檢索Customer對象時,會采用迫切左外連接(通過左外連接加載與檢索指定的對象關聯的對象)策略來檢索所有關聯的Order對象
-
lazy屬性將被忽略
-
Query的list()方法會忽略映射文件中配合的迫切左外連接策略,依舊采用延遲加載策略
4.多對一的檢索策略
-
<many-to-one>元素也有一個lazy屬性和fetch屬性
-
若fetch屬性為join,那么lazy屬性將被忽略
-
無代理延遲檢索需要增強持久化類的字節碼才能實現
-
| proxy | select | 延遲檢索 |
| no-proxy | select | 無代理延遲檢索 |
| false | select | 立即檢索 |
| proxy | join | 迫切左外連接 |
?
?
總結
以上是生活随笔為你收集整理的Hibernate之检索策略的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hibernate之对象关系映射
- 下一篇: Hibernate之检索方式(HQL/Q