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?

rzemieślnik
źródło

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.

Salandur
źródło
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();
marioosh
źródło
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.

Antonio
źródło
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.

Jon Spokes
źródło
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();
rajadilipkolli
źródło
6
Long count = (Long) session.createQuery("select count(*) from  Book").uniqueResult();
xrcwrn
źródło
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();
}
LucianoDemuru
źródło
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ć.

Vlad Mihalcea
źródło