Wie zählen wir Zeilen mit älteren Versionen von Hibernate (~ 2009)?


242

Wenn wir beispielsweise eine Tabelle Bücher haben, wie würden wir die Gesamtzahl der Buchdatensätze im Ruhezustand zählen?

Antworten:


310

Für ältere Versionen von Hibernate (<5.2):

Angenommen, der Klassenname lautet Buch:

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

Es ist mindestens ein Number, höchstwahrscheinlich ein Long.


10
Es kehrt lange zurück.
DJ_Segfault

10
Wie @Salandur vorschlägt, hat "Es ist mindestens eine Zahl" und der Zahlentyp verfügt über die Methoden "intValue ()", "longValue ()", sodass wir leicht den gewünschten primitiven Typ erhalten können, den wir wollen: ((Zahl) Kriterien.uniqueResult ()). intValue ()
Jerry Tian

5
Wenn die Entitätszuordnung nicht mithilfe eines Zeichenfolgenparameters für die Methode zum Erstellen von Kriterien gefunden werden kann, kann auch session.createCriteria (Book.class) verwendet werden
Tobias M

5
Wie @MontyBongo sagte, musste ich mich tatsächlich auf die Klasse wie return (Number) session.createCriteria(Book.class).setProjection(Projections.rowCount()).uniqueResult();
folgt

2
Dann sollten Sie keine rationale Datenbank verwenden;). Der maximale Wert von long ist 9,223372037 × 10¹⁸, was laaaaaaaaaarge
Salandur

102

In Java muss ich normalerweise int zurückgeben und dieses Formular verwenden:

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

1
Die akzeptierte Antwort auf diese Frage hat bei mir nicht funktioniert, bei Ihnen jedoch. Vielen Dank!
Jason Nichols

Ist dies der schnellste und billigste Weg, um eine Abfrage zu zählen? Ich meine Winterschlaf-weise
kommradHomer

57
Was bringt es, ein ORM zu verwenden, wenn wir SQL trotzdem codieren?
Thermz

Das ist mein Hauptanliegen (Verwendung von SQL anstelle von HQL). Ich muss verschachteltes SELECT verwenden, um die Anzahl der Zeilen zu zählen, die nach dem linken äußeren Join kommen (ich habe keine ordnungsgemäße Implementierung des linken äußeren Joins im Ruhezustand gefunden).
Pramod

15
Zunächst einmal verwendet diese Lösung kein SQL, sondern HQL. Die Verwendung von count (*) anstelle von 'select count (e) from E e' oder Kriterien funktioniert mit @EmbeddedId und Datenbanken, die die Tupelanzahl nicht unterstützen (z. B. MySQL, wo Abfragen wie 'select count ((a, b)) ) aus Tabelle1 'funktioniert nicht).
BrunoJCM

43

Die offiziellen Dokumente zum Ruhezustand sagen uns Folgendes :

Sie können die Anzahl der Abfrageergebnisse zählen, ohne sie zurückzugeben:

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

Es wird jedoch nicht immer eine IntegerInstanz zurückgegeben, daher ist es java.lang.Numberaus Sicherheitsgründen besser, sie zu verwenden .


1
+1 für eine Antwort, die die vom Hibernate-Team empfohlene Methode angibt.
Tom

3
Für mich gab dies "java.lang.ClassCastException: java.lang.Long kann nicht in java.lang.Integer umgewandelt werden", aber das
Umwandeln

2
@rogerdpack Dies liegt daran, dass Hibernate den zurückgegebenen Typ in 3.5 in Long geändert hat: community.jboss.org/wiki/HibernateCoreMigrationGuide35
Maschinerie

1
Der Rückgabetyp für die Zählfunktion kann in org.hibernate.dialect.function.StandardAnsiSqlAggregationFunctions.CountFunction( StandardBasicTypes.LONG )
Guillaume Husta

12

Du könntest es versuchen count(*)

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

Wo Booksist der Name von der class- nicht die Tabelle in der Datenbank.


Entschuldigung, aber es funktioniert nicht mit Java und Hibernate :( (Ich habe int durch Integer ersetzt, da es in Java für Typ Casting ist.)
Handwerker

Es sollte funktionieren - mit Integer statt int? Sie müssen den Klassennamen in die HQL einfügen, nicht den Tabellennamen - das einzige, was ich für falsch halten kann
Jon Spokes

1
Ich glaube, dass der Beitrag direkt darunter eher den Grundprinzipien des Ruhezustands entspricht.
Matt Sidesinger

Für mich funktioniert es nicht mit Java und Winterschlaf. was tun stattdessen?
rParvathi

6

Wenn Sie Hibernate 5+ verwenden, wird die Abfrage als geändert

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

Oder wenn Sie TypedQuery benötigen

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

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

Es sollte``` Long count = (Long) session.createQuery sein ("select count (1) from Book"). UniqueResult (); `` `es wird die Leistung verbessern
rajadilipkolli

1

Dies funktioniert in Hibernate 4 (getestet).

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

Wo getCurrentSession () ist:

@Autowired
private SessionFactory sessionFactory;


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

1

Es ist sehr einfach, führen Sie einfach die folgende JPQL-Abfrage aus:

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

Der Grund, zu dem wir ein Casting durchführen, Numberist, dass einige Datenbanken zurückkehren, Longwährend andere zurückkehren BigInteger. Aus Gründen der Portabilität ist es daher besser, in ein Casting zu Numberwechseln und ein intoder ein zu erhalten long, je nachdem, wie viele Zeilen Sie zählen möchten.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.