Criteria查詢

相信大家都很喜歡Criteria查詢,因爲它對查詢條件已經查詢實體採用鬆散的組合,不像HQL那樣需要拼字符串。 
但是又會比較牴觸它,因爲對它的不熟悉,寫複雜查詢可能會不順手,一個子查詢也可能會很麻煩。 

今天我用半天時間與大家分享Criteria查詢裏面彎路比較多的結果集distinct,這個在HQL裏面很簡單,但在Criteria查詢還真是頭疼,網上的文章也是很模糊而且討論的比較片面,我希望通過這篇文章讓大家少走彎路,多用Criteria查詢,少用HQL拼字符串。呵呵。 

Criteria的結果集最常用分兩種:對象List、List<Object[]>(投影查詢),這兩種查詢結果的distinct處理的方式也是不一樣的。稍後會分別討論。 

本文用到模型類: 

Device.java 
==================================== 
Java代碼  收藏代碼
  1. @Entity  
  2. @Table(name = "DEVICE")  
  3. public class Device extends Maintainable {  
  4.   
  5.     private Long id;  
  6.   
  7.     private String name;  
  8.   
  9.     private NodeCabinet nodeCabinet;// 所屬機櫃  
  10.   
  11.     // setter getter method ...   
  12. }  

1. 基本知識: 

1.1 Criteria不支持distinct對象結果集嗎? 
re: Criteria通過setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)方法對查詢後結果進行排重,請注意,這種方式是先查詢出可能重複的記錄然後根據每個對象的equals方法進行排重,如果不需要分頁,而且你的查詢結果集很小的話,可以使用這種方式distinct結果集。 
warning: 
  • 1. 要排重的對象要實現equals方法。
  • 2. 不能進行分頁處理,因爲是先查詢後distinct,結果會不準確。
  • 3. 查詢處理的結果集太大的話,可能存在性能問題,相同記錄會查詢多次。


示例代碼 1-1: 
Java代碼  收藏代碼
  1. Criteria c = manager.createCriteria(Device.class);  
  2. .....  
  3. criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)  
  4. List result = c.list();  


1.2 Criteria如何進行投影查詢我需要的幾個字段? 
re:Criteria通過設置projectionList就可以只查詢指定字段。 
warning:Criteria投影查詢出來的結果集格式是這樣的:List<Object[]> 前臺遍歷集合的時候需要使用數組下標訪問數據。 

示例代碼 1-2: 
Java代碼  收藏代碼
  1. Criteria c = manager.createCriteria(Device.class);  
  2. .....  
  3. ProjectionList projectionList = Projections.projectionList();  
  4. projectionList.add(Projections.property("id"));  
  5. projectionList.add(Projections.property("name"));  
  6. c.setProjection(projectionList); //生成如下SQL: select id, name from ....  
  7. List result = c.list();  



2. Criteria投影distinct查詢 

2.1 Criteria投影distinct查詢
Criteria對投影的支持比返回對象的方式支持的好很多。以下是樣例代碼,與比示例1-2代碼只有一行差別: 

示例代碼 2-1: 
Java代碼  收藏代碼
  1. Criteria c = manager.createCriteria(Device.class);  
  2. .....  
  3. ProjectionList projectionList = Projections.projectionList();  
  4. projectionList.add(Projections.property("id"));  
  5. projectionList.add(Projections.property("name"));  
  6. c.setProjection(Projections.distinct(projectionList));  // >>>> 這裏差別 生成如下SQL: select distinct id, name from ....  
  7. List result = c.list();  


2.2 分頁情況下Criteria查詢如何計算total records count 
投影情況下如何計算distinct後分頁total records count? 
re:Criteria通過Projection計算count。先算count然後在投影。計算count的可以封裝到單獨查詢方法裏。 

示例代碼: 
Java代碼  收藏代碼
  1. Criteria c = manager.createCriteria(Device.class);  
  2. .....  
  3. criteria.setProjection(Projections.countDistinct("id")); // select count(distcint id) from ...  
  4. Integer totalCount = (Integer) criteria.uniqueResult();   
  5.   
  6. ProjectionList projectionList = Projections.projectionList();  
  7. projectionList.add(Projections.property("id"));  
  8. projectionList.add(Projections.property("name"));  
  9. c.setProjection(Projections.distinct(projectionList));  // 生成如下SQL: select distinct id, name from ....  
  10. List result = c.list();  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章