`
jiakechong
  • 浏览: 211345 次
社区版块
存档分类
最新评论

Criteria查询 --- 结果集Distinct解决方案1 / 2

阅读更多
from:
http://heipark.iteye.com/blog/378540

相信大家都很喜欢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. } 

@Entity
@Table(name = "DEVICE")
public class Device extends Maintainable {

private Long id;

private String name;

private NodeCabinet nodeCabinet;// 所属机柜

// setter getter method ...
}


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(); 

Criteria c = manager.createCriteria(Device.class);
.....
criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
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(); 

Criteria c = manager.createCriteria(Device.class);
.....
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.property("id"));
projectionList.add(Projections.property("name"));
c.setProjection(projectionList); //生成如下SQL: select id, name from ....
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(); 

Criteria c = manager.createCriteria(Device.class);
.....
ProjectionList projectionList = Projections.projectionList();
projectionList.add(Projections.property("id"));
projectionList.add(Projections.property("name"));
c.setProjection(Projections.distinct(projectionList)); // >>>> 这里差别 生成如下SQL: select distinct id, name from ....
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(); 
分享到:
评论

相关推荐

    安博Hibernate最全培训资料内部版

    - **获取查询结果**:通过`list`方法获取查询结果集。 ### 五、总结 通过对以上内容的学习,可以了解到Hibernate不仅提供了一种强大的ORM解决方案,还为开发者提供了多种查询方式以适应不同的需求场景。无论是HQL...

    java工程师面试题大全-100%公司笔试题你都能碰到几个

    - **解决方案**: 在Hibernate的Criteria API中,可以通过调用`setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)`方法来去除查询结果中的重复项。 #### 二、HTTP与SMTP协议及其端口 - **HTTP**: 超文本传输协议...

    java工程师面试题大全

    - **解决方案**: 在Hibernate的Criteria API中,可以通过调用`setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)`方法来去除查询结果中的重复项。这会确保查询结果只包含唯一的根实体对象。 #### 二、HTTP与...

    java工程师面试题大全-100%公司笔试题你都能碰到几个.pdf

    **解决方案**: 使用`Criteria` API中的`setResultTransformer()`方法,并传递`Criteria.DISTINCT_ROOT_ENTITY`参数,可以有效地去除查询结果中的重复项。 **代码示例**: ```java Criteria criteria = session....

    非常实用的SQL语法与命令大全

    SQL语言的强大之处在于它能够高效地处理复杂的数据查询与操作,无论是简单的数据检索还是复杂的多表联接,SQL都能提供简洁而强大的解决方案。以下是从给定的文件信息中提取并详细解释的关键知识点: #### SELECT...

Global site tag (gtag.js) - Google Analytics