hibernate學習筆記(檢索策略) – JAVA編程語言程序開發技術文章

默認的立即檢索策略的缺點;
1.select語句的數目太多,需要頻繁的訪問數據庫。會影響檢索性能。如果需要查詢n個對象。那麼必須執行n+1次select查詢語句。這種檢索策略沒有利用sql的連接查詢功能。例如:select * from customers left outer join orders on customers.id=orders.customer_id
2.以上select語句使用sql的左外連接查詢功能,能夠在一條select語句中查詢出customers表中的所有記錄,以及匹配orders表的記錄。
3.在應用邏輯隻需要訪問customer對象。而不需要訪問order對象的場合,加載order對象完全是多餘的操作。這些多餘的order對象白白浪費瞭許多內存空間。

在一對多關聯級別,使用延遲檢索策略。
對於<set>元素,應該優先使用延遲檢索策略。如果隻是查一的一方。適用立即檢索策略,會把多的一方也給查出來。
<set name="orders" invers="true" lazy="true">設置lazy為true即設置延遲檢索策略。
此時運行Customer customer=(Customer)session.get(Customer.class,new Long(1))僅立即檢索Customer對象,執行以下select語句。
select * from customer where id=1

在一對多關聯級別,使用延遲檢索策略。
customer對象的order變量引用集合代理類實例,當應用程序第一次訪問它,例如調用customer.getOrders().iterator()方法時,hibernate會初始化這個集合代理類實例。在初始化過程中到數據庫檢索所有customer關聯的order對象。執行以下select語句:select * from order where customer_id=1;

延遲檢索策略:
優點:由應用程序決定需要加載哪些對象。可以避免執行多餘的select語句。以及避免加載應用程序不需要訪問的對象。因此能提高檢索性能。並且能節省內存空間。
缺點:應用程序如果希望訪問遊離狀態的代理類實例。必須保證它在持久化狀態時已經被初始化瞭
適用范圍:
1.一對多或者多對多關聯。
2.應用程序不需要立即訪問或者根本不會訪問的對象。

在多對一關聯級別,使用左外聯機檢索策略:
默認情況下,多對一關聯使用左外連接檢索策略。
如果把order.hbm.xml文件的<many-oto-one>元素的outer-join的屬性設為true,總是使用左外連接檢索策略。如:
Order order=(Order)session.get(Order.class,new Long(1));
在運行session.get()方法時,hibernate執行以下select語句。select * from orders left outer join Customers on orders.customer_id=customers.id where order.id=1

左外連接檢索策略:
優點:1.對應用程序完全透明,不管對象處於持久化狀態,還是遊離狀態,應用程序都可以方便的從一個對象導航到與它關聯的對象。
2.使用瞭外連接。select語句數目少瞭。
缺點:可能會加載應用程序中不需要訪問的對象。浪費內存空間。復雜的數據庫表連接也會影響檢索性能。
適用范圍:
多對一或者一對一關聯
應用程序中需要立即訪問的對象。
數據庫系統具有良好的表連接性能。

在程序中顯示指定左外連接檢索策略。
1.在映射文件中設定的檢索策略是固定的。要麼為延遲檢索。要麼為立即檢索,要麼為外連接檢索
在應用邏輯是多種多樣的。有些情況下需要延遲檢索。而有些情況下需要外連接檢索。
2.hibernate允許在應用程序中覆蓋映射文件中設定的檢索策略。由應用程序在運行時決定檢索對象圖的深度。

以下session的方法都用於檢索oid為1的customer對象。
session.createQuery("from Customer as c where c.id=1");
session.createQuery("from Customer as c left join fetch c.orders where c.id=1");
在執行第一個方法時,將使用映射文件配置檢索策略
在執行第二個方法時,在HQL語句中顯式指定左外連接檢索關聯的order對象。因此會覆蓋映射文件配置的檢索策略。不管在Customer.hbm.xml文件中<set>元素的lazy屬性是true還是false,hibernate都會執行以下select語句。
select * from Customers left outer join Orders on Customer.id=Orders.customer_id where Customers.id=1
作者:yy008871

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。