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.