【问题标题】:Hibernate count issue using 2 fields使用 2 个字段的休眠计数问题
【发布时间】:2012-06-15 11:25:30
【问题描述】:

在 SparePart 表中,行的唯一性由 materialName 和 materialNumber 的组合给出,我想做的是获取现在可用的 Spare Parts 总数。

我尝试过使用 count(distinct ...) 但它只适用于一个字段而不是两个。

带有内部查询的 SQL 查询(使用休眠查询语言)如下所示:

select count(*) from (
     select distinct materialName, materialNo from SparePart
) as col

【问题讨论】:

    标签: hibernate jpa hql


    【解决方案1】:

    使用子查询+group by,然后过滤代表特定组的第一个ID,最后统计所有匹配过滤器的ID:

    SELECT COUNT(sp2) FROM SparePart sp2 WHERE EXISTS
      (SELECT sp.materialName, sp.materialNo
              FROM SparePart sp
              GROUP BY sp.materialName, sp.materialNo
              HAVING MIN(sp.id)=sp2.id)
    

    【讨论】:

      【解决方案2】:

      您可以使用休眠方言来完成此任务。为此,请创建您自己的方言,扩展所使用的 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<SparePart> root = criteria.from(SparePart.class);
      criteria.select(builder.function("pairCountDistinct", Long.class, root.get(SparePart_.materialName), root.get(SparePart_.materialNo)));
      final long result = entityManager.createQuery(criteria).getSingleResult();
      // some close actions
      

      【讨论】:

        【解决方案3】:

        您可以使用 Criteria API 进行尝试。

        ProjectionList projectionList = Projections.projectionList();        
        projectionList.add(Projections.property("materialName"));
        projectionList.add(Projections.property("materialNo"));
        
        Criteria criteria = session.createCriteria(SparePart.class); 
        criteria.setProjection(Projections.distinct(projectionList);  
        criteria.setProjection(Projections.rowCount());
        
        Long results = criteria.uniqueResult();
        

        另外,它可能需要一些修改,因为我没有尝试过,根据您的查询映射。

        【讨论】:

          猜你喜欢
          • 2020-05-19
          • 2011-07-20
          • 2011-02-26
          • 2012-09-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多