【问题标题】:Count of the result of a Hibernate Criteria group by - total grouped records returnedHibernate Criteria group by 的结果计数 - 返回的总分组记录
【发布时间】:2011-11-16 10:37:53
【问题描述】:

我有一个基于条件的查询,具有以下分组:

Projections.projectionList()
    .add(Property.forName("xyz").group()));

生成的 SQL 是(专有的,因此已清理):

select this_.XYZ as y0_ from FOO.BAR this_ WHERE [long where clause] 
    group by this_.XYZ

现在,从概念上讲,我想用 count(*) 包装查询结果,这样数据就永远不会从数据库中返回,而只是计数。像这样:

select count(*) from (
  select this_.XYZ as y0_ from FOO.BAR this_ WHERE [long where clause] 
      group by this_.XYZ
)

可能有数千行我不需要并且我对高性能感兴趣,所以我不希望这些数据通过网络传输。

我的基于条件的搜索有许多条件。我无法真正重建它,所以我真的需要坚持 Criteria。

当然,添加 rowCount 或 count("xyz") 没有帮助,因为它只报告每行 1。

我目前正在这样做以获取计数:

ScrollableResults scroll = criteria.scroll();
scroll.last();
int count = scroll.getRowNumber();

它有效,但需要很长时间才能返回计数(如果重要,请在 Oracle 上)。

我可以按照我的建议去做吗?

【问题讨论】:

    标签: hibernate count group-by criteria scrollableresults


    【解决方案1】:

    使用Subqueries API 并创建内部标准。

    第一个条件是分组依据的主要条件。行数取自第二个标准 100% 保证结果。

    第一条件

    DetachedCriteria criteria = getNominationMainCriteria(nominationFilterDto, appraiserId);
            criteria.add(Property.forName(PROFFESIONAL_STRING + ".hcpId").eqProperty("subProf.hcpId"));
            criteria.setProjection(Projections.projectionList().add(
                    Projections.groupProperty(PROFFESIONAL_STRING + "." + Constants.HCP_ID)));
    

    第二个标准

    Criteria nativeCriteria = getSession().createCriteria(Professional.class, Constants.SUB_PROFESSIONAL);
            nativeCriteria.add(Subqueries.propertyEq(Constants.SUB_PROFESSIONAL + "." + Constants.HCP_ID, criteria));
            nativeCriteria.setProjection(Projections.projectionList().add(Projections.rowCount()));
            rowCount = (Long) nativeCriteria.uniqueResult();
    

    【讨论】:

      【解决方案2】:

      从概念上来说,

      select count(*) from (
        select this_.XYZ as y0_ from FOO.BAR this_ WHERE [long where clause] 
            group by this_.XYZ
      )
      

      一样
      select count(distinct (this_.XYZ)) from FOO.BAR this_ WHERE [long where clause] 
      

      因此,您可以使用 Projections.countDistinct((String propertyName)) 为您的 Criteria 选择不同的 propertyName。

      session.createCriteria(Foo.class)
              .add(myOrigianlCriterionObject)
              .setProjection(Projections.countDistinct("XYZ"));
      

      【讨论】:

      • 非常酷!我不知道 Projections.countDistinct。它工作得很好,现在速度非常快。非常非常感谢肯。
      • 此解决方案适用于按一列分组。对于多个列,我在这里写了一个解决方案:stackoverflow.com/a/65030998/2114737
      猜你喜欢
      • 2012-01-19
      • 2015-12-12
      • 2012-08-10
      • 1970-01-01
      • 1970-01-01
      • 2015-05-11
      • 1970-01-01
      • 2017-07-17
      • 1970-01-01
      相关资源
      最近更新 更多