hibernate的n 1查詢問題

2021-09-01 18:17:28 字數 2535 閱讀 8745

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查詢變成了...