Як ми рахуємо рядки, використовуючи старіші версії Hibernate (~ 2009)?


242

Наприклад, якщо у нас є таблиця "Книги", як би ми підрахували загальну кількість записів книг із сплячим режимом?

Відповіді:


310

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

Припустимо, що назва класу: Book:

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

Це принаймні а Number, швидше за все, а Long.


10
Повертається довго.
dj_segfault

10
Як підказує @Salandur, "Це принаймні число", а тип номера має методи "intValue ()", "longValue ()", тому ми можемо легко отримати бажаний примітивний тип, який ми хочемо: ((Кількість) критерії.uniqueResult intValue ()
Джеррі Тіан

5
Якщо відображення сутності не вдається знайти за допомогою рядкового параметра методу створення критеріїв, також може бути використаний session.createCriteria (Book.class)
Tobias M,

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)" ) з table1 'не працює).
BrunoJCM

43

Ось що нам повідомляють про це офіційні сплячі документи :

Ви можете порахувати кількість результатів запиту, не повертаючи їх:

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

Однак це не завжди повертає Integerекземпляр, тому його краще використовувати java.lang.Numberдля безпеки.


1
+1 за відповідь, яка дає команді, що перебуває в сплячому режимі, рекомендований метод.
Том

3
Для мене це дало "java.lang.ClassCastException: java.lang.Long не можна кидати на java.lang.Integer", але кастинг на Лонг замість цього працює ...
rogerdpack

2
@rogerdpack це тому, що Hibernate змінив повернутий тип в 3.5 на Long: community.jboss.org/wiki/HibernateCoreMigrationGuide35
обладнання

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

12

Ви можете спробувати count(*)

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

Звідки Booksназва class- не таблиця в базі даних.


вибачте, але це не працює з Java та Hibernate :( (я замінив інт на Integer, як це є у Java для кастингу типів.)
майстер

Це має працювати - з Integer замість int? Вам потрібно ввести ім'я класу в HQL, а не ім'я таблиці - це єдине, що я можу подумати, що може бути не так
Jon Spokes

1
Я вважаю, що повідомлення безпосередньо під цим більше відповідає основним принципам сну.
Метт Сайдінгер

для мене це не працює з java та в сплячку. що робити замість цього?
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

Це працює в сплячому режимі 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і отримати а intчи a long, залежно від того, скільки рядків ви очікуєте для підрахунку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.