`

Hibernate Criteria中的三种Distinct

 
阅读更多

案例:

/**
 * 客户拜访计划
 * 
 **/
@Entity
@Table(name = "cus_visit")
public class Visit {
	/**
	 * 同行人
	 */
	private Set<Employee> partners;
	@ManyToMany(targetEntity = Employee.class, cascade = { CascadeType.MERGE },fetch = FetchType.LAZY)
	@Cascade(value = { org.hibernate.annotations.CascadeType.SAVE_UPDATE,org.hibernate.annotations.CascadeType.DELETE })
	@JoinTable(name = "cus_visit_employee", joinColumns = { @JoinColumn(name = "visit_id") }, inverseJoinColumns = { @JoinColumn(name = "employee_id") })
	@Fetch(FetchMode.SELECT)
	public Set<Employee> getPartners() {
		return partners;
	}
	public void setPartners(Set<Employee> partners) {
		this.partners = partners;
	}
}

Criteria创建:

Criteria criteria = getSession().createCriteria(Visit.class)
				.setFirstResult(pageInfo.getStartIndex())
				.setMaxResults(pageInfo.getNumPerPage());

查询条件

private void addQueryCause(Criteria criteria, Visit visit) {
criteria.createAlias("partners", "partner");
if(visit.getPartners()!=null){
			Set<Employee> partnerSet = visit.getPartners();
			for(Employee employee :partnerSet){
				criteria.add(Restrictions.or(Restrictions.like(
						"partner.empNo", employee.getEmpNo(),MatchMode.ANYWHERE),Restrictions.like(
						"partner.name", employee.getName(),MatchMode.ANYWHERE)));
				}
			
		}
//其他查询条件...
}

第一种:对查询完毕之后的结果进行Distinct

addQueryCause(idsOnlyCriteria, visit);
criteria.setResultTransformer(criteria.DISTINCT_ROOT_ENTITY);
return criteria.list();



第二种:只查询一个属性,并对这个属性进行Distinct

addQueryCause(idsOnlyCriteria, visit);
criteria.setProjection(Projections.distinct(Projections.id()));
return criteria.list();



第三种:使用子查询,实现整条记录的Distinct

DetachedCriteria idsOnlyCriteria = DetachedCriteria.forClass(Visit.class);
idsOnlyCriteria.setProjection(Projections.distinct(Projections.id()));
addQueryCause(idsOnlyCriteria, visit);

criteria.add(Subqueries.propertyIn("id", idsOnlyCriteria));

return criteria.list();

第三种实现依赖于第二种功能,把条件都放到对id查询的限制上,之后在查询主记录只需要使主键IN子查询结果就行了。最后生成的SQL语句:

    select
        this_.id as id1_61_0_,
       ....
    from
        cus_visit this_ 
    where
        this_.id in (
            select
                distinct this_.id as y0_ 
            from
                cus_visit this_ 
            left outer join
                cus_visit_employee partners3_ 
                    on this_.id=partners3_.visit_id 
            left outer join
                core_employee partner1_ 
                    on partners3_.employee_id=partner1_.emp_no 
            where
                (
                    this_.planer=? 
                    or partner1_.emp_no=?
                )
        ) 
    order by
        this_.id asc limit ?




分享到:
评论

相关推荐

    hibernate criteria 分组 排序 关联

    在Hibernate中,使用`Criteria`进行查询时,可以通过添加排序条件来对结果集进行排序。`Criteria`提供了一个非常灵活的方式来实现这一点。 **示例代码**: ```java Criteria criteria = session.createCriteria...

    Hibernate中Criteria的用法

    而在Hibernate提供的多种查询方式中,Criteria API是一种非常灵活且强大的查询工具,它支持复杂的条件组合以及分组、排序等功能,为开发者提供了更为方便的查询手段。 #### 二、Criteria简介 Criteria是Hibernate...

    Hibernate学习资料(离线查询)

    在Hibernate中进行查询的方式有很多,包括HQL、Criteria API以及Native SQL等。本篇主要关注的是使用Criteria API来进行查询。 ### Criteria API Criteria API是Hibernate提供的一个非常强大的查询工具,它可以...

    criteria进阶查询

    Criteria API 是 Hibernate 提供的一种高级查询机制,它允许开发者在不直接编写 HQL 或 SQL 语句的情况下,构建复杂的数据库查询。这个API提供了一种面向对象的方式来构建查询,使得查询更具有可读性和灵活性。 1. ...

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

    - **Hibernate**是一个开放源代码的**对象关系映射(ORM)**解决方案,它能够帮助开发者将Java应用程序中的对象数据与数据库中的表格进行映射。 - **版本**:此处提到的是Hibernate 2.2版本,虽然当前最新的...

    进阶查询herbinate

    在使用Hibernate进行数据操作时,`Criteria` API是一种灵活且强大的查询方式。它允许我们根据不同的条件构造复杂的查询语句,而无需直接编写SQL。在标题和描述中提到的“进阶查询herbinate”实际上是指使用Hibernate...

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

    在Hibernate中,使用dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)可以去除重复项。 2. HTTP协议及端口、SMTP协议及端口 HTTP(HyperText Transfer Protocol)是一种超文本传输协议,使用80端口。SMTP...

    Hql语句注意事项总结

    使用预编译语句(如Hibernate的`Criteria` API或`NamedQuery`)可以降低这种风险。 - **数据类型匹配**:确保数组中的元素类型与数据库字段类型匹配,以避免类型转换错误。 总之,理解和熟练掌握这些Hql注意事项是...

    java工程师面试题大全

    在Hibernate中,如果需要去除查询结果中的重复项,可以使用`Criteria.DISTINCT_ROOT_ENTITY`作为`ResultTransformer`。这将确保返回的实体集合中没有重复的根实体。例如: ```java Criteria criteria = session....

    杭州公司笔试题目.doc

    dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) 是 Hibernate 框架中用于去除重复项的方法。Criteria.DISTINCT_ROOT_ENTITY 是一个标记,用于指定结果集的去重方式。在 Hibernate 中,我们可以使用 ...

    DetachedCriteria查询

    DetachedCriteria 是 Hibernate 中的一种离线查询对象,它可以在不依赖 Session 的情况下生成动态 SQL 语句并进行查询。下面是 DetachedCriteria 查询的详细知识点: 创建 DetachedCriteria 对象 DetachedCriteria...

    300+道中高级java工程师面试题大全含答案文档下载

    1. **Hibernate离线查询去除重复项**:在Hibernate中,使用Criteria API时,可以设置ResultTransformer为`Criteria.DISTINCT_ROOT_ENTITY`来去除查询结果中的重复实体。 2. **HTTP与SMTP协议及端口**:HTTP是用于...

    java软件工程师面试题

    Hibernate 提供了 `Criteria.DISTINCT_ROOT_ENTITY` 结果转换器,用于在查询时去除结果集中的重复实体。在 Criteria 查询中,添加 `dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);` 可以确保返回的实体...

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

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

    java工程师面试题

    Hibernate框架提供了Criteria接口,可以使用`Criteria.DISTINCT_ROOT_ENTITY`作为结果转换器来去除查询结果中的重复项。 2. HTTP与SMTP协议及其端口: - HTTP(超文本传输协议)默认使用80端口,用于客户端与...

    Java面试题

    Hibernate中的Criteria查询可以通过设置ResultTransformer为DISTINCT_ROOT_ENTITY来去除查询结果中的重复实体。`dc.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);` 这一行代码的作用是确保返回的实体结果...

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

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

    java_软件工程师面试题

    为了实现这一目标,开发者可以使用`Criteria` API中的`setResultTransformer`方法,将查询结果转换器设置为`Criteria.DISTINCT_ROOT_ENTITY`。这一操作会确保查询结果中只包含唯一的实体对象,即使这些对象可能在...

    hql语句查询

    **HQL语句查询详解** Hibernate Query Language (HQL) 是Hibernate框架中用于查询数据库的面向对象的语言。...在实际项目中,HQL和Criteria API都是常见的查询方式,根据项目需求和团队习惯可以选择合适的方法。

Global site tag (gtag.js) - Google Analytics