Jak liczymy wiersze przy użyciu starszych wersji Hibernacji (~ 2009)?


242

Na przykład, jeśli mamy tabelę książek, w jaki sposób policzymy całkowitą liczbę rekordów książek w trybie hibernacji?

Odpowiedzi:


310

W przypadku starszych wersji Hibernacji (<5.2):

Zakładając, że nazwa klasy to Book:

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

Jest to przynajmniej Number, najprawdopodobniej Long.


10
Zwraca długi.
— dj_segfault

10
Jak sugeruje @Salandur, „Jest to co najmniej liczba”, a typ liczby ma metody „intValue ()”, „longValue ()”, dzięki czemu możemy łatwo uzyskać pożądany typ pierwotny: ((Number) kryteria.uniqueResult ()). intValue ()
— Jerry Tian

5
Jeśli nie można znaleźć odwzorowania encji przy użyciu parametru ciągu do metody tworzenia kryteriów, można również użyć session.createCriteria (Book.class)
— Tobias M

5
Jak powiedział @MontyBongo, tak naprawdę musiałem odnieść się do klasy w ten sposób: return (Number) session.createCriteria(Book.class).setProjection(Projections.rowCount()).uniqueResult();
— bcmoney

2
Wtedy nie powinieneś używać racjonalnej bazy danych;). Maksymalna wartość długa to 9,223372037 × 10¹⁸, czyli laaaaaaaaaarge
— Salandur

102

W Javie zazwyczaj muszę zwrócić int i użyć tego formularza:

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

1
Przyjęta odpowiedź na to pytanie nie działała dla mnie, ale twoje. Dzięki!
— Jason Nichols

czy to najszybszy i najtańszy sposób na zliczenie zapytania? Znaczy hibernacji mądry
— kommradHomer

57
Po co używać ORM, jeśli i tak kodujemy SQL?
— thermz

To mój główny problem (używanie SQL zamiast HQL). Muszę użyć zagnieżdżonego WYBORU tylko do zliczenia liczby wierszy przychodzących po lewym złączeniu zewnętrznym (nie znalazłem poprawnej implementacji lewego łącznika zewnętrznego w stanie hibernacji).
— Pramod

15
Po pierwsze, to rozwiązanie nie korzysta z SQL, to HQL. I użycie count (*) zamiast „select count (e) from E e” lub kryteria działa z @EmbeddedId i bazami danych, które nie obsługują liczby krotek (np. MySQL, gdzie zapytania takie jak „select count ((a, b)) ) z tabeli 1 'nie działa).
— BrunoJCM,

43

Oto, co oficjalne dokumenty dotyczące hibernacji mówią nam o tym:

Możesz policzyć liczbę wyników zapytania bez zwracania ich:

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

Jednak nie zawsze zwraca Integerinstancję, dlatego lepiej jest używać jej java.lang.Numberze względów bezpieczeństwa.


1
+1 za odpowiedź, która daje zalecaną przez zespół Hibernacji metodę.
— Tom

3
Dla mnie to dało „java.lang.ClassCastException: java.lang.Long nie mogą być oddane do java.lang.Integer” ale odlewania do długiego zamiast działa ...
— rogerdpack

2
@rogerdpack dzieje się tak, ponieważ Hibernate zmienił zwracany typ w 3.5 na Long: community.jboss.org/wiki/HibernateCoreMigrationGuide35
— maszyneria

1
Typ zwracany dla funkcji zliczania można znaleźć w org.hibernate.dialect.function.StandardAnsiSqlAggregationFunctions.CountFunction( StandardBasicTypes.LONG )
— Guillaume Husta

12

Możesz spróbować count(*)

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

Gdzie Booksjest nazwa class- nie tabela w bazie danych.


przepraszam, ale nie działa z Javą i Hibernacją :( (zastąpiłem int Integer, ponieważ jest w Javie do rzutowania typu.)
— rzemieślnik

Powinien działać - z Integer zamiast int? Musisz umieścić nazwę klasy w HQL, a nie nazwę tabeli - to jedyna rzecz, która może być błędna
— Jon Spokes

1
Uważam, że post bezpośrednio poniżej jest bardziej zgodny z podstawowymi zasadami Hibernacji.
— Matt Sidesinger

dla mnie to nie działa z java i hibernacji. co zamiast tego zrobić?
— rParvathi

6

Jeśli używasz Hibernacji 5+, zapytanie zostanie zmodyfikowane jako

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

Lub jeśli potrzebujesz TypedQuery

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

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

Powinno to być `` Długie zliczanie = (Długa) session.createQuery ("select count (1) from Book"). UniqueResult (); `` poprawi wydajność
— rajadilipkolli

1

Działa to w Hibernacji 4 (Testowane).

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

Gdzie getCurrentSession () to:

@Autowired
private SessionFactory sessionFactory;


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

1

To bardzo proste, wystarczy uruchomić następujące zapytanie JPQL:

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

Powodem, dla którego przesyłamy, Numberjest to, że niektóre bazy danych zwrócą się, Longpodczas gdy inne powrócą BigInteger, więc ze względu na przenośność lepiej jest rzucić na a Numberi uzyskać a intlub a long, w zależności od liczby wierszy, których spodziewasz się policzyć.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.