当前位置: 首页 > 知识库问答 >
问题:

hibernate标准计数超过group by

黄景胜
2023-03-14
select
count(*) OVER () as totalRecords
  from users u
  group by
    u.first_name,
    u.last_name,
    u.age
  order by u.age DESC
OFFSET 1 ROWS FETCH NEXT 1 ROWS ONLY;
public Long getTotalCount() {
        ProjectionList groupBy = projectionList();
        groupBy.add(groupProperty("firstName"), "first_name");
        groupBy.add(groupProperty("last_name"), "last_name");
        groupBy.add(groupProperty("age"), "age");
        groupBy.add(Projections.rowCount());

        return (Long) getSession().createCriteria("User")
                .setProjection(groupBy)
                .uniqueResult();
    }

共有1个答案

翟俊茂
2023-03-14

我只是花了几个小时试图找到一个方法,最后让它发挥作用。

免责声明

用普通标准API做一个最优的查询是不可能的。最佳选择是select COUNT(*)FROM(此处按查询分组)select COUNT(*)OVER()。两者都不可能。若要获得最佳查询,请尽可能使用纯SQL。对于我的情况,使用普通SQL是不可能的,因为我构造了一个非常复杂的逻辑来构建标准,并且我还希望使用相同的逻辑来解析聚合计数(以解析分页的页计数)。

@Entity
class MyEntity {

private Long aggregateRowCount;

@Formula(value="count(*) over()")
public Long getAggregateRowCount() {
    return aggregateRowCount;
}

public void setAggregateRowCount(Long aggregateRowCount) {
    this.aggregateRowCount = aggregateRowCount;
}
Criteria criteria = // construct query here
ProjectionList projectionList = // construct Projections.groupProperty list here
projectionList.add(Projections.property("aggregateRowCount")); // this is our custom entity field with the @Formula annotation
criteria.setProjection(projectionList);
criteria.setMaxResults(1); 
criteria.setResultTransformer(AggregatedCountResultTransformer.instance());
List<?> res = builder.criteria.list();
if (res.isEmpty()) return 0L;
return (Long) res.get(0);
SELECT groupbyfield1, groupbyfield2, count(*) over()
FROM ...
GROUP BY groupbyfield1, groupbyfield2
LIMIT 1;

如果没有限制1,结果将是

field1 | field2 | count
a      | b      | 12356
a      | c      | 12356
...    | ...    | 12356

但是我们添加了限制1(Criteria.setMaxResults(1);),因为第一行已经包含了行数,这就是我们所需要的。

最后,我们的AggegatedCountResultTransformer:

class AggregatedCountResultTransformer implements ResultTransformer {

private static final AggregatedCountResultTransformer instance = new AggregatedCountResultTransformer();

public static ResultTransformer instance() {
    return instance;
}

@Override
public Object transformTuple(Object[] values, String[] fields) {
    if (values.length == 0) throw new IllegalStateException("Values is empty");
    return values[values.length-1]; // Last value of selected fields (the count)
}

@SuppressWarnings("rawtypes")
@Override
public List transformList(List allResults) {
    return allResults; // This is not actually used?
}
 类似资料:
  • 我正在尝试实现以下内容: 问:我如何用JPA 2标准实现这个? 我可以单独获得asCount结果,但不知道如何将其加入公司 提前感谢。 PS 1。有一个类似的线程使用HiberNate应用编程接口询问子级计数:HiberNate子级计数标准 2。另一个描述该主题的有用线程: JPA CriteriaBuilder——按一对多关系中关联实体的数量排序

  • 问题内容: 我正在尝试使用Hibernate进行复杂的查询。我一直倾向于“标准”,但是我开始怀疑这是不可能的,因此任何建议都将有所帮助。 我有一个如下的实体结构: 这些实体与您期望的相关: 现在,我希望能够采用一组属性/值对(字符串)并找到包含 所有 属性/值对的所有实例。在“值”中,只有attribute和localAttributeName中的一个为非空值,因此属性名称可以与localAttr

  • 嗨,我想写一个查询使用条件:以下查询必须使用条件创建: “从S2中选择不同的(s2Taxper),其中s2Tc='601'和s2Txcd!=”” 提前谢谢

  • 问题内容: 注意:这个问题确实是Split pandas dataframe字符串条目复制到单独行的重复,但是此处提供的答案更通用,更有意义,因此,在所有方面,我选择不删除线程 我有一个具有以下格式的“数据集”: 我想通过复制每个id的所有值来规范化它: 我正在做的是应用split-apply-combine的使用原理,为每个组创建一个 我创建了一个列进行分组,该列仅对行中的id进行计数: 我复制

  • 问题内容: 嗨,我有这个大型的OraclehibernateWeb应用程序,它似乎给出了此错误 并且我需要由某人测试的Java代码作为hibernate用户定义的组件,以便尽可能容易地将其添加到屏幕上的搜索Java类中,有人可以拥有经过测试的组件? 问题答案: 我尝试从链接下面的代码,它似乎工作得很好,万一将来链接被打破,我会粘贴代码。 保持简单保持微笑:)