hibernate的連線查詢

2021-06-13 21:48:46 字數 4950 閱讀 6996

連線查詢:

1、    迫切左外連線查詢和左外連線查詢:

我們看以下**,這段**將覆蓋對映檔案中的檢索策略,顯示指定採用迫切左外連線查詢。

hql查詢方式:

query query=session.createquery(「from customer c left join fetch c.orders o where c.name       like 『zhao%』 」);

list list=query.list();

for(int i=0;i

customer customer=(customer)list.get(i); }

//qbc檢索方式:

list list=session.createcriteria(customer.class).setfetchmode(「orders」,fetchmode.eager)

.add(expression.like(「name」,」zhao%」,matchmode.start).list();

for(int i=0;i

customer customer=(customer)list.get(i); }

我們看到在hql以及qbc查詢中分別通過left join fetch和fetchmode.eager來指定採用迫切左外連線檢索策略,當採用了迫切左外連線檢索策略時,當進行檢索時即執行查詢的list()方法時,將會立即初始化用來容納關聯實體的集合物件元素,如果在實體對映配置檔案中對關聯實體設定了延遲載入,那麼此時將會忽略延遲載入設定,而採用迫切左外連線策略,並且立即用關聯實體物件填充集合物件元素,即使用order物件填充customer物件的orders集合。因此這種檢索策略會馬上建立關聯實體物件,此時我想你一定會想到這種檢索策略會同時檢索出customer和order實體物件對應的資料,並且分別建立這兩個物件。恭喜你答對了,因此上面**會生成類似如下的sql語句:

select * from customer c left join order o on c.id=o.id where c.name like 『zhao%』;

如果我們忽略了fetch關鍵字,就變成了左外連線查詢,如下面**:

query query=session.createquery(「from customer c left join c.orders o where c.name       like 『zhao%』 」);

list list=query.list();

for(int i=0;i

object objs=(object)list.get(i);

customer customer=(customer) objs[0];

order order=(order)objs[1]; }

我們可以看到採用左外連線查詢返回的結果集中包含的是物件陣列,物件陣列中的每個元素存放了一對相互關聯的customer物件和order物件,而迫切左外連線會返回customer物件,與customer物件相關聯的order物件存放在customer物件的集合元素物件中,這就是迫切左外連線和左外連線查詢的其中乙個區別(這兩種檢索生成的sql語句是一樣的),另乙個區別是當使用左外連線時,對關聯物件的檢索會依照實體對映配置檔案所指定的策略,而不會像迫切左外連線那樣忽略它,比如此時對customer物件關聯的order物件採用延遲載入,那麼左外連線檢索也會使用延遲載入機制檢索order物件。

2、內連線,迫切內連線以及隱式內連線:

若採用迫切內連線通過一下**可以實現:

query query=session.createquery(「from customer c inner join fetch c.orders o where c.name       like 『zhao%』 」);

list list=query.list();

for(int i=0;i

customer customer=(customer)list.get(i); }

這段**將會採用迫切內連線檢索,對集合元素的檢索策略以及返回結果集中的物件型別都採用與迫切左外連線一樣的方式,我這裡就不再贅述,另外qbc查詢不支援迫切內連線檢索。

如果去掉fetch就是內連線檢索,如下面**:

query query=session.createquery(「from customer c innerjoin c.orders o where c.name       like 『zhao%』 」);

list list=query.list();

for(int i=0;i

object objs=(object)list.get(i);

customer customer=(customer) objs[0];

order order=(order)objs[1]; }

內連線檢索,對集合元素的檢索策略以及返回結果集中的物件型別都採用與左外連線一樣的方式,qbc查詢也同樣支援內連線檢索,如下**:

list list=session.createcriteria(customer.class)

.add(expression.like(「name」,」zhao%」,matchmode.start))

.createcriteria(「orders」)

.add(expression.like(「ordernumber」,」t」,matchmode.start)).list();

上面**等價於如下的hql語句:

select c from customer c join c.orders o where c.name like 『zhao%』 and o.ordernummber like 『t%』;因此可以採用下面的方式訪問結果集:

for(int i=0;i

customer customer=(customer)list.get(i); }

由此可見,採用內連線查詢時,hql與qbc查詢有不同的預設行為,hql會檢索出成對的customer和order物件,而qbc僅會檢索出customer物件。如果qbc查詢想檢索出成對的customer和order物件,可以採用如下**:

list list=session.createcriteria(customer.class)

.createalias(「orders」,」o」)

.add(expression.like(「this.name」,」zhao%」,matchmode.start))

.add(expression.like(「ordernumber」,」t」,matchmode.start))

.returnmap()

.list();

for(int i=0;i

map map=(map)list.get(i);

customer customer=(customer)map.get(「this」);

order order=(order)map.get(「o」); }

「o」和」this」分別是orders集合和customer物件的別名。

在hql查詢中,還有一種查詢成為隱式內連線,我們看下面的hql語句,

from order o where o.customer.name like 』 zhao% 』;這個語句通過o.customer.name訪問與order物件關聯的customer物件的name屬性,儘管沒有使用join關鍵字,其實隱式指定了採用內連線檢索,它和下面這條hql語句等價:

from order o join o.customer c where c.name like 『zhao%』;

隱式內連線只適用於多對一和一對一關聯,不適用於一對多和多對多關聯,另外qbc查詢不支援隱式內連線檢索。

3、右外連線檢索:

由於fetch關鍵字只能應用於innner join和left join,因此對於右外連線檢索而言,就不存在所謂的迫切右外連線查詢了,使用右外連線見如下**:

query query=session.createquery(「from customer c right join c.orders o where c.name       like 『zhao%』 」);

list list=query.list();

for(int i=0;i

object objs=(object)list.get(i);

customer customer=(customer) objs[0];

order order=(order)objs[1]; }

右外連線檢索,對集合元素的檢索策略以及返回結果集中的物件型別都採用與左外連線一樣的方式。

4、交叉連線:

對於不存在關聯關係的兩個實體物件,不能使用內連線查詢,也不能使用外連線查詢,此時可以使用具有sql風格的交叉連線,如下面**:

select c.id,c.name,c.age,o.id,o.ordernumber,o.customer_id

from customer c,order o;

這個hql語句將會執行交叉連線檢索,而且將會返回customer表和order表的笛卡兒積關聯結果。

5、連線查詢執行時檢索策略總結:

①、如果在hql和qbc查詢中沒有指定檢索策略,那麼將會使用對映配置為件中指定的檢索策略,但是這裡有乙個例外,那就是hql檢索總是會忽略實體對映配置檔案中對關聯實體指定的迫切左外連線檢索策略,也就是說如果配置檔案中指定對關聯實體採用迫切走外連線檢索,但是在hql查詢語句中沒有指定這種檢索策略,此時hibernate將會忽略這種檢索策略,而依然採用立即檢索。因此如果希望採用迫切左外連線檢索,就必須在hql語句中明確指定。

②、如果在hql或者qbc檢索中明確指定了檢索策略,就會覆蓋配置檔案中的預設檢索策略,在hql查詢中通過left join fetch和inner join fetch來明確指定檢索策略,在qbc查詢中通過fetchmode.default,fetchmode.eager,fetchmode.lazy來明確指定檢索策略。

①、             目前的hibernate的各種版本中,只允許在乙個查詢中迫切左外連線檢索乙個集合,即只允許存在乙個一對多關聯,但是允許存在多個一對一和多對多關聯

原文出處:

Hibernate 連線查詢

package com.gordon.test import j a.util.arrays import j a.util.list import org.hibernate.query import org.hibernate.session import org.hibernate.trans...

hibernate多表連線查詢,主表分頁的實現

第一步 查詢資料的總數 session s hibernatesessionfactory.getsession detachedcriteria idsonlycriteria detachedcriteria.forclass category.class,c hibernate多表連線查詢,主...

hibernate多表連線 查詢的解決方案

大家在用hibernate的時候總會遇到多表連線的查詢,遇到這種問題 總是各種糾結。方案1 建立檢視 事先在資料庫裡面建立檢視。然後建立這個檢視的實體類,指定乙個主鍵。然後建立這個檢視的查詢。方案2 給實體類加臨時屬性hql查詢補充。上 實體類 entity table name flow ru i...