Sortieren mit Ruhezustand

Sortieren mit Ruhezustand

1. Überblick

Dieser Artikel beschreibthow to Sort with Hibernate, wobei sowohl die Hibernate Query Language (HQL) als auch die Criteria-API verwendet werden.

Weitere Lektüre:

Ruhezustand: speichern, beibehalten, aktualisieren, zusammenführen, saveOrUpdate

Eine schnelle und praktische Anleitung für Schreibmethoden im Ruhezustand: Speichern, beibehalten, aktualisieren, zusammenführen, saveOrUpdate.

Read more

Objekte im Ruhezustand löschen

Kurzanleitung zum Löschen eines Objekts im Ruhezustand.

Read more

Winterschlaf-Abfangjäger

Eine schnelle und praktische Anleitung zum Erstellen von Hibernate-Interceptors.

Read more

2. Sortieren mit HQL

Das Sortieren mit Hibernates HQL ist so einfach wie das Hinzufügen derOrder By-Klausel zur HQL-Abfragezeichenfolge:

String hql = "FROM Foo f ORDER BY f.name";
Query query = sess.createQuery(hql);

Nachdem dieser Code ausgeführt wurde, generiert Hibernate die folgende SQL-Abfrage:

Hibernate: select foo0_.ID as ID1_0_, foo0_.NAME as NAME2_0_ from
    FOO foo0_ order by foo0_.NAME

Die Standardsortierreihenfolge ist aufsteigend. Aus diesem Grund ist die Bestellbedingungasc nicht in der generierten SQL-Abfrage enthalten.

2.1. Verwenden einer expliziten Sortierreihenfolge

Um die Sortierreihenfolge manuell anzugeben, müssen Sie die Bestellrichtung in die Abfragezeichenfolge vonHQLaufnehmen:

String hql = "FROM Foo f ORDER BY f.name ASC";
Query query = sess.createQuery(hql);

In diesem Beispiel wurde das Setzen derasc-Klausel in der HQL in die generierte SQL-Abfrage aufgenommen:

Hibernate: select foo0_.ID as ID1_0_, foo0_.NAME as NAME2_0_
    from FOO foo0_ order by foo0_.NAME ASC

2.2. Sortieren nach mehr als einem Attribut

DerOrder By-Klausel in der HQL-Abfragezeichenfolge können mehrere Attribute zusammen mit einer optionalen Sortierreihenfolge hinzugefügt werden:

String hql = "FROM Foo f ORDER BY f.name DESC, f.id ASC";
Query query = sess.createQuery(hql);

Die generierte SQL-Abfrage ändert sich entsprechend:

Hibernate: select foo0_.ID as ID1_0_, foo0_.NAME as NAME2_0_
    from FOO foo0_ order by foo0_.NAME DESC, foo0_.ID ASC

2.3. Festlegen der Sortierrangfolge von Nullwerten

Wenn das zu sortierende Attributnull-Werte hat, muss das RDMS standardmäßig die Priorität festlegen. Diese Standardbehandlung kann durch Platzieren vona NULLS FIRST or NULLS LAST clause in the HQL query string überschrieben werden.

In diesem einfachen Beispiel werden Nullen am Ende der Ergebnisliste eingefügt:

String hql = "FROM Foo f ORDER BY f.name NULLS LAST";
Query query = sess.createQuery(hql);

Sehen wir uns dieis null then 1 else 0-Klausel ingenerated SQL query an:

Hibernate: select foo0_.ID as ID1_1_, foo0_.NAME as NAME2_1_,
foo0_.BAR_ID as BAR_ID3_1_, foo0_.idx as idx4_1_ from FOO foo0_
order by case when foo0_.NAME is null then 1 else 0 end, foo0_.NAME

2.4. Eins zu viele Beziehungen sortieren

Analysieren wir einen komplexen Sortierfall:sorting entities in a one to many relation -Bar, der eine Sammlung vonFoo Entitäten enthält.

Dazu kommentieren wir die Sammlung mitthe Hibernate @OrderBy annotation. Wir geben das Feld an, nach dem die Bestellung erfolgt, sowie die Richtung:

@OrderBy(clause = "NAME DESC")
Set fooList = new HashSet();

Beachten Sie das Argument vonclausefür die Annotation. Dies gilt nur für@OrderByvon Hibernate im Vergleich zu ähnlichen JPA-Annotationen von@OrderBy. Ein weiteres Merkmal, das diesen Ansatz von seinem JPA-Äquivalent unterscheidet, ist, dass das Argumentclauseangibt, dass die Sortierung anhand der SpalteNAMEder TabelleFOOund nicht anhand der Spaltenameerfolgt. s Attribut vonFoo.

Betrachten wir nun die tatsächliche Sortierung vonBars undFoos:

String hql = "FROM Bar b ORDER BY b.id";
Query query = sess.createQuery(hql);

Dieresulting SQL statement zeigen, dass die sortiertenFoo’s infooList: platziert sind

Hibernate: select bar0_.ID as ID1_0_, bar0_.NAME as NAME2_0_ from BAR bar0_
    order by bar0_.ID Hibernate: select foolist0_.BAR_ID as BAR_ID3_0_0_,
    foolist0_.ID as ID1_1_0_, foolist0_.ID as ID1_1_1_, foolist0_.NAME as
    NAME2_1_1_, foolist0_.BAR_ID as BAR_ID3_1_1_, foolist0_.idx as idx4_1_1_
    from FOO foolist0_ where foolist0_.BAR_ID=? order by foolist0_.NAME desc

Eine Sache zu beachten ist, dass esnot possible to to sort Lists ist, wie es bei JPA der Fall war. In der Dokumentation zum Ruhezustand heißt es:

"Hibernate ignoriert derzeit @OrderBy auf @ElementCollection auf z. Liste . Die Reihenfolge der Elemente ist wie von der Datenbank zurückgegeben und undefiniert. “

Als Randnotiz wäre es möglich, diese Einschränkung zu umgehen, indem die alte XML-Konfiguration für den Ruhezustand verwendet und das Element<List..>durch ein Element<Bag…>ersetzt wird.

3. Sortieren nach Ruhezustandskriterien

Die Kriterienobjekt-API stellt die KlasseOrderals Haupt-API zum Verwalten der Sortierung bereit.

3.1. Sortierreihenfolge einstellen

Die KlasseOrderhat zwei Methoden zum Festlegen der Sortierreihenfolge:

  • *asc*(String attribute): Sortiert die Abfrage nachattribute in aufsteigender Reihenfolge.

  • *desc*(String attribute): Sortiert die Abfrage nachattribute in absteigender Reihenfolge.

Beginnen wir mit einem einfachen Beispiel - Sortieren nach einem einzelnenid-Attribut:

Criteria criteria = sess.createCriteria(Foo.class, "FOO");
criteria.addOrder(Order.asc("id"));

Beachten Sie, dass das Argument für die Methodeasczwischen Groß- und Kleinschreibung unterscheidet und mit denname des zu sortierenden Attributs übereinstimmen sollte.

Die Objekt-API von Hibernate Criteria legt explizit eine Sortierreihenfolge fest. Dies spiegelt sich in der vom Code generierten SQL-Anweisung wider:

Hibernate: select this_.ID as ID1_0_0_, this_.NAME as NAME2_0_0_
    from FOO this_ order by this_.ID sac

3.2. Sortieren nach mehr als einem Attribut

Das Sortieren nach mehreren Attributen erfordert nur das Hinzufügen einesOrder-Objekts zurCriteria-Instanz, wie im folgenden Beispiel:

Criteria criteria = sess.createCriteria(Foo.class, "FOO");
criteria.addOrder(Order.asc("name"));
criteria.addOrder(Order.asc("id"));

Die in SQL generierte Abfrage lautet:

Hibernate: select this_.ID as ID1_0_0_, this_.NAME as NAME2_0_0_ from
    FOO this_ order by this_.NAME asc, this_.ID sac

3.3. Festlegen der Sortierrangfolge von Nullwerten

Wenn das zu sortierende Attributnull-Werte hat, muss das RDMS standardmäßig die Priorität festlegen. Die Hibernate Criteria Object API macht es einfach, diesen Standard undplace nulls at the end einer aufsteigenden geordneten Liste zu ändern:

Criteria criteria = sess.createCriteria(Foo.class, "FOO");
criteria.addOrder(Order.asc("name").nulls(NullPrecedence.LAST));

Hier ist die zugrunde liegende Abfrage vonSQL- mit der Klauselis null then 1 else 0:

Hibernate: select this_.ID as ID1_1_1_, this_.NAME as NAME2_1_1_,
    this_.BAR_ID as BAR_ID3_1_1_, this_.idx as idx4_1_1_, bar2_.ID as
    ID1_0_0_, bar2_.NAME as NAME2_0_0_ from FOO order by case when
    this_.NAME is null then 1 else 0 end, this_.NAME asc

Alternativ können wir auchplace the nulls at the beginning einer absteigenden geordneten Liste verwenden:

Criteria criteria = sess.createCriteria(Foo.class, "FOO");
criteria.addOrder(Order.desc("name").nulls(NullPrecedence.FIRST));

Die entsprechende SQL-Abfrage folgt - mit deris null then 0 else 1-Klausel:

Hibernate: select this_.ID as ID1_1_1_, this_.NAME as NAME2_1_1_,
    this_.BAR_ID as BAR_ID3_1_1_, this_.idx as idx4_1_1_, bar2_.ID as
    ID1_0_0_, bar2_.NAME as NAME2_0_0_ from FOO order by case when
    this_.NAME is null then 0 else 1 end, this_.NAME desc

Beachten Sie, dassif the attribute to sort by is a primitive type like an int, a PresisitenceException will thrown.

Wenn beispielsweise der Wert vonf.anIntVariable null ist, wird die Abfrage ausgeführt:

String jql = "Select f from Foo as f order by f.anIntVariable desc NULLS FIRST";
Query sortQuery = entityManager.createQuery(jql);

wird werfen:

javax.persistence.PersistenceException: org.hibernate.PropertyAccessException:
Null value was assigned to a property of primitive type setter of
com.cc.jpa.example.Foo.anIntVariable

4. Fazit

In diesem Artikel wird das Sortieren mit Ruhezustand erläutert. Dabei werden die verfügbaren APIs sowohl für einfache Entitäten als auch für Entitäten in einer Eins-zu-Viele-Beziehung verwendet.

Die Implementierung dieses Tutorial zum Sortieren im Ruhezustand finden Sie inthe github project - dies ist ein Eclipse-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein.