You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Querydsl JPQLQuery如何不生成列表直接获取查询结果记录数

QueryDSL 3.7.4 分组查询直接获取总数方案

针对带group by的查询需要统计总记录数的场景,不需要先拉取全量结果列表再算size,可通过以下两种方式实现:

方案1:使用listResults方法直接获取总计数

QueryDSL 3.x内置了listResults()方法,会自动生成count统计查询,不需要拉取业务数据,直接返回总记录数:

Expression[] groupByExpression = // 获取group by表达式
Predicate whereCondition = // 获取查询条件谓词

long count = query.from(myEntityName)
                  .where(whereCondition)
                  .groupBy(groupByExpression)
                  .listResults(constructorExpression)
                  .getTotal();

该方案兼容性最高,不需要修改原有查询的分组、条件逻辑,直接替换原有list().size()即可生效。

方案2:构造distinct分组键的count查询(性能最优)

分组后的总记录数等价于分组字段组合的去重计数,直接构造计数查询即可:

Expression[] groupByExpression = // 获取group by表达式
Predicate whereCondition = // 获取查询条件谓词

// 多字段分组时用tuple封装分组键
Expression<?> groupKey = groupByExpression.length == 1 
    ? groupByExpression[0] 
    : Projections.tuple(groupByExpression);

long count = query.from(myEntityName)
                  .where(whereCondition)
                  .singleResult(JPAExpressions.select(groupKey).distinct().count());

该方案没有多余的投影解析逻辑,性能略优于方案1,适合对性能要求极高的场景。

注意事项

  • 两种方案都只会执行count统计查询,不会加载全量分组数据,大数据量下性能比原有实现提升非常明显
  • 不建议直接使用JPAQuery原生的count()方法,该方法在带group by的查询中会返回每个分组的单独计数,无法拿到总组数

内容的提问来源于stack exchange,提问作者Joel George

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 21:57:02