如何计算多列的不同

时间:2012-02-07 21:21:43

标签: hibernate jpa jpa-2.0

如何使用JPA条件API执行以下操作:

select count(distinct column1, column2) from table

使用CriteriaBuilder.countDistinct在一个列/路径上执行此操作很简单,但是如何在两个路径/列上执行此操作?

3 个答案:

答案 0 :(得分:4)

这是一个迟到的答案:-)虽然我不确定事情是否发生了变化。

最近我遇到了同样的需求,并使用concat解决了这个问题,即通过将列连接到伪列,然后在伪列上连接countDistinct

但我无法使用criteriaBuilder.concat,因为它使用||生成了JPQL以进行连接,Hibernate had trouble with

幸运的是@Formula,因此,我将伪列映射到@Formula的字段:

@Entity
public class MyEntity {
  @Column(name="col_a")
  private String colA;

  @Column(name="col_b")
  private String colB;

  @Formula("concat(col_a, col_b)") // <= THE TRICK
  private String concated;
}

这样我最终可以使用concated的{​​{1}}字段:

CriteriaBuilder.countDistinct

我希望JPA(或希望已经)支持//... Expression<?> exp = criteriaBuilder.countDistinct(entity.get("concated")); criteriaQuery.select(exp); TypedQuery<Long> query = entityManager.createQuery(criteriaQuery); return query.getSingleResult(); 多列,然后可以避免所有这些混乱。

答案 1 :(得分:1)

您可以使用hibernate方言执行此任务。要做到这一点,创建自己的方言,扩展DB使用的方言(list of all dialects),然后注册新功能。例如,我使用带有InnoDB引擎的MySQL 5:

public final class MyDialect extends MySQL5InnoDBDialect {
    public MyDialect() {
        super();
        registerFunction("pairCountDistinct", new SQLFunctionTemplate(LongType.INSTANCE, "count(distinct ?1, ?2)"));
    }
}

然后在persistence.xml中添加新属性:

<property name="hibernate.dialect" value="com.example.dialect.MyDialect" />

现在您可以使用此功能:

// some init actions
final CriteriaBuilder builder = entityManager.getCriteriaBuilder();
final CriteriaQuery<Long> criteria = builder.createQuery(Long.class);
final Root<SomeEntity> root = criteria.from(SomeEntity.class);
criteria.select(builder.function("pairCountDistinct", Long.class, root.get(SomeEntity_.field1), root.get(SomeEntity_.field2)));
final long result = entityManager.createQuery(criteria).getSingleResult();
// some close actions

答案 2 :(得分:0)

似乎没有办法用JPA2

来做到这一点