Как мы подсчитываем строки, используя более старые версии Hibernate (~ 2009)?


242

Например, если у нас есть таблица Books, как бы мы посчитали общее количество записей книги в режиме гибернации?

Ответы:


310

Для более старых версий Hibernate (<5.2):

Предполагая, что имя класса - Book:

return (Number) session.createCriteria("Book")
                  .setProjection(Projections.rowCount())
                  .uniqueResult();

Это как минимум a Number, скорее всего a Long.


10
Возвращается долго.
dj_segfault

10
Как подсказывает @Salandur, «Это по крайней мере число», а тип Number имеет методы «intValue ()», «longValue ()», поэтому мы можем легко получить желаемый тип примитива, который нам нужен: ((Number) attribute.uniqueResult) ()). intValue ()
Джерри Тян

5
Если сопоставление сущностей невозможно найти с помощью строкового параметра в методе создания критериев, также можно использовать session.createCriteria (Book.class)
Тобиас М

5
Как сказал @MontyBongo, мне действительно нужно было сослаться на класс следующим образом: return (Number) session.createCriteria(Book.class).setProjection(Projections.rowCount()).uniqueResult();
bcmoney

2
Тогда не стоит использовать рациональную базу данных;). Максимальное значение long составляет 9,223372037 × 10¹⁸, то есть laaaaaaaaaarge
Salandur

102

В Java мне обычно нужно вернуть int и использовать эту форму:

int count = ((Long)getSession().createQuery("select count(*) from Book").uniqueResult()).intValue();

1
Принятый ответ на этот вопрос не сработал для меня, но ваш сработал. Спасибо!
Джейсон Николс

Это самый быстрый и дешевый способ подсчета запросов? я имею в виду спящий - мудрый
kommradHomer

57
Какой смысл использовать ORM, если мы все равно будем кодировать SQL?
thermz

Это моя главная проблема (использование SQL вместо HQL). Я должен использовать вложенный SELECT только для подсчета количества строк, которые идут после левого внешнего соединения (я не нашел правильной реализации левого внешнего соединения в спящем режиме).
Прамод

15
Во-первых, это решение не использует SQL, это HQL. И использование count (*) вместо «select count (e) from E e» или критериев работает с @EmbeddedId и базами данных, которые не поддерживают подсчет кортежей (например, MySQL, где запросы типа «select count» ((a, b) ) из таблицы 1 'не работает).
BrunoJCM

43

Вот что официальные документы по гибернации говорят нам об этом:

Вы можете посчитать количество результатов запроса, не возвращая их:

( (Integer) session.createQuery("select count(*) from ....").iterate().next() ).intValue()

Однако он не всегда возвращает Integerэкземпляр, поэтому его лучше использовать java.lang.Numberдля безопасности.


1
+1 за ответ, который дает рекомендуемый метод для команды Hibernate.
Том

3
Для меня это дало "java.lang.ClassCastException: java.lang.Long не может быть приведен к java.lang.Integer", но вместо этого работает приведение к Long ...
rogerdpack

2
@rogerdpack это потому, что Hibernate изменил возвращаемый тип в 3.5 на Long: community.jboss.org/wiki/HibernateCoreMigrationGuide35
механизм

1
Тип возврата для функции count можно найти в org.hibernate.dialect.function.StandardAnsiSqlAggregationFunctions.CountFunction( StandardBasicTypes.LONG )
Гийом Хуста,

12

Вы могли бы попробовать count(*)

Integer count = (Integer) session.createQuery("select count(*) from Books").uniqueResult();

Где Booksимя от class- не таблица в базе данных.


извините, но он не работает с Java и Hibernate :( (я заменил int на Integer, как это было в Java для приведения типов.)
craftman

Должно работать - с Integer вместо int? Вам нужно поместить имя класса в HQL, а не имя таблицы - это единственное, что я могу подумать, что это может быть неправильно
Джон Спокс

1
Я полагаю, что публикация непосредственно под этим больше соответствует основным принципам Hibernate.
Мэтт Сидесингер

для меня это не работает с Java и Hibernate. что делать вместо этого?
rParvathi

6

Если вы используете Hibernate 5+, запрос будет изменен как

Long count = session.createQuery("select count(1) from  Book")
                    .getSingleResult();

Или если вам нужен TypedQuery

Long count = session.createQuery("select count(1) from  Book",Long.class)
                        .getSingleResult();

6
Long count = (Long) session.createQuery("select count(*) from  Book").uniqueResult();

Это должно быть``` Long count = (Long) session.createQuery ("select count (1) from Book"). UniqueResult (); `` `это улучшит производительность
rajadilipkolli

1

Это работает в Hibernate 4 (проверено).

String hql="select count(*) from  Book";
Query query= getCurrentSession().createQuery(hql);
Long count=(Long) query.uniqueResult();
return count;

Где getCurrentSession ():

@Autowired
private SessionFactory sessionFactory;


private Session getCurrentSession(){
return sessionFactory.getCurrentSession();
}

1

Это очень просто, просто запустите следующий запрос JPQL:

int count = (
(Number)
    entityManager
    .createQuery(
        "select count(b) " +
        "from Book b")
    .getSingleResult()
).intValue();

Причина, по которой мы приводим данные, Numberзаключается в том, что некоторые базы данных возвращаются, Longа другие - возвращаются BigInteger, поэтому для удобства переноса вам лучше привести к типу a Numberи получить a intили a long, в зависимости от того, сколько строк вы ожидаете подсчитать.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.