我有一个基于Criteria的查询,其中包含以下分组:
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上)。
我可以做我提出的建议吗?
答案 0 :(得分:7)
从概念上讲,
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))
为您的条件选择不同的propertyName。
session.createCriteria(Foo.class)
.add(myOrigianlCriterionObject)
.setProjection(Projections.countDistinct("XYZ"));
答案 1 :(得分:0)
使用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();