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?

Handwerker
quelle

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.

Salandur
quelle
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();
Marioosh
quelle
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 .

Antonio
quelle
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.

Jon spricht
quelle
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();
Rajadilipkolli
quelle
6
Long count = (Long) session.createQuery("select count(*) from  Book").uniqueResult();
xrcwrn
quelle
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();
}
LucianoDemuru
quelle
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.

Vlad Mihalcea
quelle