Как получить количество строк в запросах Hibernate Criteria с использованием MySQL 5?
Мы в основном использовали HQL. Но у нас есть эта сложная форма поиска, которая содержит много объединений, поэтому я подумал, что мне повезет с использованием критериев (никогда раньше не было). Мне нравится синтаксис намного лучше, и он соответствует сложной форме, которую мы имеем.
Мой первый инстинкт должен был сделать .list().size()
ДО того, как я применил setMaxResults
а также setFirstResult
, Который, конечно, медленный и ленивый и полный боров ресурса.
После небольшого поиска в Google я нашел пример, который использует ScrollableResults. Но пост сказал, что MySQL не поддерживает курсоры. Это был пост 2004 года. Здесь, в 2012 году, мы используем MySQL 5 с таблицами InnoDB. Поэтому я думаю, что мы поддерживаем курсоры. Тогда я нашел использовать проекции.
Так что, не будучи гуру Hibernate, я заблудился на лучшем пути. Мы МОЖЕМ использовать DB2 в будущем, поэтому я представляю, какое бы решение я не использовал, оно должно работать в DB2 и MySQL 5.
Есть идеи? Я думаю, как минимум, я мог бы использовать собственный HQL, чтобы получить счетчик (*).
Спасибо
ОБНОВИТЬ
Я просто вставил это в:
ScrollableResults scr = crit.scroll();
scr.last();
int rowCount = scr.getRowNumber() + 1;
против
int rowCount = crit.list().size();
Оба, прежде чем я поставлю свои предельные / начальные значения. Это бежало НАМНОГО быстрее. Поэтому я предполагаю, что курсор работает для конкретной БД и результатов. Я даже добавил туда несколько соединений, и, кажется, все еще намного быстрее.
Любой вклад, если это все еще хорошая идея?
4 ответа
Вы могли бы использовать критерии setProjection(Projections.property("id"))
,
Я думаю, что получение счетчика с помощью отдельного запроса - единственный вариант, если вы хотите применить нумерацию страниц, используя setFirstResult
а также setMaxResults
,
Наверняка crit.list().size()
загрузит полный набор строк в виде сущностей в сеансе Hibernate.
Метод ScrollableResults.last()
зависит от реализации драйвера JDBC, и это может быть очень медленно, потому что полный ResultSet
может быть загружен полностью, даже если объекты Hibernate еще не созданы.
Лучший вариант - использовать crit.setProjection(Projections.rowCount()).uniqueResult()
И вы можете включить hashcode()
в вашем коде, то есть
criteria.setProjection(Projections.rowCount()).uniqueResult().hashCode()