sql和hql中join語句區別,以及hibernate中內連線,迫切內連線,左外連線,迫切左外連線,右外連線的區別(合集)...

langgufu314發表於2012-07-24

第一:sql和hql中join語句區別

1,sql中join操作可以用到任何兩個表中,其包括inner join,left join,right join,通過on指定連線條件。

 

2,hql是sql的物件導向版,也包括inner join,left join,right join。但其join只能用在有關聯關係的物件間,無關聯關係的物件不能使用,且由於有關聯關係的物件其關聯外來鍵已經在配置檔案中配置了,故而hql中的join操作無須指定on 條件,Hibernate會自動附加連線條件。

 

 

第二:hibernate中內連線,迫切內連線,左外連線,迫切左外連線,右外連線的區別

連線查詢:
關係型資料庫之所以強大,其中一個原因就是可以統一使用表來管理同類資料資訊,並且可以在相關資料之間建立關係。作為支援關係型資料庫的SQL語句來說,自然要對全面發揮這種強大功能提供支援,這個支援就是連線查詢。

同樣作為一種關係型資料庫的持久層框架,Hibernate也對連線查詢提供了豐富的支援,在Hibernate中通過HQL與QBC兩種查詢方式都可以支援連線查詢。

下面這一部分我們將通過這兩種查詢技術,來詳細討論有關 Hibernate對連線查詢支援的各個細節。在講解連線查詢之前,我們先來回憶一下在第一部分中講解的有關實體關聯關係的對映,在實體的配置檔案中可以通過配置集合元素來指定對關聯實體的對映以及檢索策略。

因此我們可以在實體對映配置檔案中,指定關聯實體檢索策略,對關聯實體的檢索策略可以指定為“延遲檢索”,“立即檢索”,“迫切左外連線檢索”,如下所示對與Customer實體關聯的Order實體設定延遲載入:,這種在實體對映配置檔案中設定的檢索策略,稱為預設檢索策略,但是這種預設檢索策略是可以被覆蓋的,那就是在程式程式碼當中可以動態指定各種迫切檢索策略來覆蓋預設檢索策略。

 

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 <list.size();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 <list.size();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 <list.size();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 <list.size();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 <list.size();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 <list.size();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 <list.size();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 <list.size();i++){>
Object[] objs=(Object[])list.get(i);
Customer customer=(Customer) objs[0];
order order=(Order)objs[1];
}
右外連線檢索,對集合元素的檢索策略以及返回結果集中的物件型別都採用與左外連線一

 

總結:

第一:左外連線和迫切左外連線檢索策略區別

HQL:左連線採用配置的預設載入規則,返回物件陣列。迫切左外連線檢索策略採用立即查詢,返回物件集。

QBC:支援迫切左外連線檢索策略,返回物件集。

 

第二:內連線和迫切內連線檢索策略區別

HQL:內連線採用配置的預設載入規則,返回物件陣列。迫切內外連線檢索策略採用立即查詢,返回物件集。

QBC:採用內連線檢索策略時返回的和HQL的迫切內外連線檢索策略一樣,返回物件集,但也可以通過別的方式返回物件對映集。

第三:右外連線
右外連線沒有相應的迫切右外連線,所以HQL只能採用右外連線查詢出物件陣列。

相關文章