Счетчик результата группы Критерии гибернации по общему количеству возвращенных сгруппированных записей
У меня есть запрос на основе критериев со следующей группировкой:
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
Теперь, концептуально, я хочу обернуть результаты запроса счетчиком (*) так, чтобы данные никогда не возвращались из базы данных, только счет. Как это:
select count(*) from (
select this_.XYZ as y0_ from FOO.BAR this_ WHERE [long where clause]
group by this_.XYZ
)
Могут быть тысячи строк, которые мне не нужны, и я заинтересован в высокой производительности, поэтому я не хочу, чтобы эти данные передавались по сети.
Мой поиск на основе критериев имеет множество условий. Я не могу реально восстановить его, поэтому мне действительно нужно придерживаться критериев.
Конечно, добавление rowCount или count("xyz") не помогает, потому что он просто сообщает 1 для каждой строки.
В настоящее время я делаю это, чтобы получить счет:
ScrollableResults scroll = criteria.scroll();
scroll.last();
int count = scroll.getRowNumber();
Это работает, но требуется много времени, чтобы вернуться с подсчетом (на Oracle, если это имеет значение).
Могу ли я сделать то, что я предлагаю?
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))
выбрать отличное свойство name для ваших критериев.
session.createCriteria(Foo.class)
.add(myOrigianlCriterionObject)
.setProjection(Projections.countDistinct("XYZ"));
Использовать 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();