在
session
的快取中存放的是相互關聯的物件圖。預設情況下,當
hibernate
從資料庫中載入
customer
物件時,會同時載入所有關聯的
order
物件。以
customer
和order
類為例,假定
orders
表的customer_id
外來鍵允許為
null,圖1
列出了customers
表和orders
表中的記錄。
以下session
的find()
方法用於到資料庫中檢索所有的
customer
物件:
list customerlists=session.find("from customer as c");
執行以上
find()
方法時,
hibernate
將先查詢
customers
表中所有的記錄,然後根據每條記錄的
id,到
orders
表中查詢有參照關係的記錄,
hibernate
將依次執行以下
select
語句:
select * from customers;
select * from orders where customer_id=1;
select * from orders where customer_id=2;
select * from orders where customer_id=3;
select * from orders where customer_id=4;
通過以上5條
select
語句,hibernate
最後載入了4個
customer
物件和5
個order
物件,在記憶體中形成了一幅關聯的物件圖,參見圖2。
在檢索與
customer
關聯的order
物件時,使用了預設的立即檢索策略。這種檢索策略存在兩大不足: (
1)select
語句的數目太多,需要頻繁的訪問資料庫,會影響檢索效能。如果需要查詢n個
customer
物件,那麼必須執行
n+1次
select
查詢語句。這就是經典的
n+1次
select
查詢問題。這種檢索策略沒有利用
sql的連線查詢功能,例如以上5條
select
語句完全可以通過以下1條
select
語句來完成:
select * from customers left outer join orders
on customers.id=orders.customer_id
以上select
語句使用了
sql的左外連線查詢功能,能夠在一條
select
語句中查詢出
customers
表的所有記錄,以及匹配的
orders
表的記錄。 (
2)在應用邏輯只需要訪問
customer
物件而不需要訪問
order
物件的場合下,載入
order
物件完全是多餘的操作,這些多餘的
order
物件白白浪費了許多記憶體空間。
為了解決以上問題,
hibernate
提供了兩種檢索策略:延遲檢索策略和迫切左外連線檢索策略 1
、延遲檢索策略能避免多餘載入應用程式不需要訪問的關聯物件,
hibernate3
開始已經預設是
lazy=true
了;lazy=true
時不會立刻查詢關聯物件,只有當需要關聯物件(訪問其屬性)時才會發生查詢動作。 2
、迫切左外連線檢索策略則充分利用了
sql的外連線查詢功能,能夠減少
select
語句的數目。
可以在對映檔案中定義連線抓取方式。
或者使用
hql的
left outer join.
或者在條件查詢中使用
setfetchmode(fetchmode.join)
customer ctm = (customer)session.createcriteria(customer.class)
.setfetchmode(「order」.join)
.add(restrictions.ideq(customer_id));
HIBERNATE的N 1查詢問題
在session的快取中存放的是相互關聯的物件圖。預設情況下,當hibernate從資料庫中載入customer物件時,會同時載入所有關聯的order物件。以customer和order類為例,假定orders表的customer id外來鍵允許為null,圖1列出了customers表和order...
Hibernate解決n 1問題
觀點 對於n 1問題的理解。一般而言說n 1意思是,無論在一對多還是多對一當查詢出n條資料之後,每條資料會關聯的查詢1次他的關聯物件,這就叫做n 1。但是我的理解是,本來所有資訊可以一次性查詢出來,也就是簡單的連表查詢,但是hibernate會首先查詢1次得到當前物件,然後當前物件裡面的n個關聯物件...
hibernate中的n 1問題
前提 hibernate預設表與表的關聯方法是fetch select 不是fetch join 這都是為了懶載入而準備的。1 一對多 在1的這方,通過1條sql查詢得到了1個物件,由於關聯的存在 那麼又需要將這個物件關聯的集合取出,所以合集數量是n還要發出n條sql,於是本來的1條sql查詢變成了...