Sortierung mit JPA

Sortieren mit JPA

1. Überblick

Dieser Artikel zeigt die verschiedenen Möglichkeiten vonJPA can be used for sorting.

Weitere Lektüre:

Frühlingsdaten JPA @Query

Erfahren Sie, wie Sie die Annotation @Query in Spring Data JPA verwenden, um benutzerdefinierte Abfragen mit JPQL und nativem SQL zu definieren.

Read more

JPA-Attributkonverter

Sehen Sie sich die Zuordnung von JDBC-Typen zu Java-Klassen in JPA mithilfe von Attributkonvertern an.

Read more

Arbeiten mit Kotlin und JPA

Erfahren Sie, wie Sie JPA in Ihrem Kotlin-Projekt verwenden können.

Read more

2. Sortieren mit JPA / JQL API

Die Verwendung von JQL zum Sortieren erfolgt mit Hilfe derOrder By-Klausel:

String jql ="Select f from Foo as f order by f.id";
Query query = entityManager.createQuery (jql);

Basierend auf dieser Abfrage generiert JPA die folgenden geradlinigenSQL statement:

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_
    from Foo foo0_ order by foo0_.id

Beachten Sie, dass bei den SQL-Schlüsselwörtern in der JQL-Zeichenfolge nicht die Groß- und Kleinschreibung beachtet wird, sondern die Namen der Entitäten und ihrer Attribute.

2.1. Sortierreihenfolge einstellen

Standardmäßigthe sorting order is ascending, kann jedoch explizit in der JQL-Zeichenfolge festgelegt werden. Genau wie in reinem SQL lauten die Bestelloptionenasc unddesc:

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

Diegenerated SQL query enthalten dann die Bestellrichtung:

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_
    from Foo foo0_ order by foo0_.id desc

2.2. Sortieren nach mehr als einem Attribut

Um nach mehreren Attributen zu sortieren, werden diese zur Klausel order by der JQL-Zeichenfolge hinzugefügt:

String jql ="Select f from Foo as f order by f.name asc, f.id desc";
Query sortQuery = entityManager.createQuery(jql);

Beide Sortierbedingungen werden in der Anweisunggenerated SQL queryangezeigt:

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_
    from Foo foo0_ order by foo0_.name asc, foo0_.id desc

2.3. Festlegen der Sortierrangfolge von Nullwerten

Die Standardpriorität von Nullen ist datenbankspezifisch, kann jedoch über die KlauselNULLS FIRST oderNULLS LAST in der HQL-Abfragezeichenfolge angepasst werden.

Hier ist ein einfaches Beispiel: Sortieren nachname vonFoo in absteigender Reihenfolge und Platzieren vonNulls am Ende:

Query sortQuery = entityManager.createQuery
    ("Select f from Foo as f order by f.name desc NULLS LAST");

Die generierte SQL-Abfrage enthältis null the 1 else 0 end clause (3. Zeile):

Hibernate: select foo0_.id as id1_4_, foo0_.BAR_ID as BAR_ID2_4_,
    foo0_.bar_Id as bar_Id2_4_, foo0_.name as name3_4_,from Foo foo0_ order
    by case when foo0_.name is null then 1 else 0 end, foo0_.name desc

2.4. Eins zu viele Beziehungen sortieren

Schauen wir uns nun die Anwendungsbeispiele an und betrachten wir einen Anwendungsfall mitsorting entities in a one to many relation -Bar, der eine Sammlung vonFoo Entitäten enthält.

Wir möchten die Entitäten vonBarund auch ihre Sammlung von Entitäten vonFooortieren - JPA ist für diese Aufgabe besonders einfach:

  1. Sortieren der Sammlung: Fügen Sie eine Annotation vonOrderByvor der Sammlung vonFooin die EntitätBarein:

    @OrderBy("name ASC")
    List  fooList;
  2. Sortieren der Entität, die die Sammlung enthält:

    String jql = "Select b from Bar as b order by b.id";
    Query barQuery = entityManager.createQuery(jql);
    List barList = barQuery.getResultList();

Beachten Sie, dass die Annotation@OrderBy optional ist. In diesem Fall wird sie jedoch verwendet, da wir dieFoo-Auflistung allerBar sortieren möchten.

Schauen wir uns dieSQL queryan, die an das RDMS gesendet wurden:

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_ID2_0_0_, foolist0_.id as id1_4_0_,
foolist0_.id as id1_4_1_, foolist0_.BAR_ID as BAR_ID2_4_1_,
foolist0_.bar_Id as bar_Id2_4_1_, foolist0_.name as name3_4_1_
from Foo foolist0_
where foolist0_.BAR_ID=? order by foolist0_.name asc

Die erste Abfrage sortiert die Entität des übergeordnetenBar. Die zweite Abfrage wird generiert, um die Sammlung der untergeordnetenFoo-Entitäten zu sortieren, die zuBar gehören.

3. Sortieren mit der JPA Criteria Query Object API

Bei JPA-Kriterien ist die MethodeorderByeine Alternative aus einer Hand, um alle Sortierparameter festzulegen: Sowohl dieorder directionals auch dieattributes to sort von können eingestellt werden. Es folgt die API der Methode:

  • orderBy (CriteriaBuilder.asc): Sortiert in aufsteigender Reihenfolge.

  • orderBy (CriteriaBuilder.desc): Sortiert in absteigender Reihenfolge.

Jede Instanz vonOrderwird mit dem Objekt CriteriaBuilderüber die Methodenasc oderdescerstellt.

Hier ist ein kurzes Beispiel: Sortieren vonFoos nachname:

CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Foo.class);
Root from = criteriaQuery.from(Foo.class);
CriteriaQuery select = criteriaQuery.select(from);
criteriaQuery.orderBy(criteriaBuilder.asc(from.get("name")));

Das Argument für dieget-Methode unterscheidet zwischen Groß- und Kleinschreibung, da es mit dem Namen des Attributs übereinstimmen muss.

Im Gegensatz zu einfachem JQL ist die JPA Criteria Query Object APIforces an explicit order directionin der Abfrage enthalten. Beachten Sie in der letzten Zeile dieses Codeausschnitts, dass das ObjektcriteriaBuilderdie aufsteigende Sortierreihenfolge durch Aufrufen der Methodeascangibt.

Wenn der obige Code ausgeführt wird, generiert JPA die unten gezeigte SQL-Abfrage. JPA Criteria Object generiert eine SQL-Anweisung mit einer explizitenasc-Klausel:

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_
    from Foo foo0_ order by foo0_.name asc

3.1. Sortieren nach mehr als einem Attribut

Um nach mehr als einem Attribut zu sortieren, übergeben Sie einfach eineOrder-Instanz an dieorderBy-S-Methode für jedes Attribut, nach dem sortiert werden soll.

Hier ein kurzes Beispiel: Sortieren nachname undid in der Reihenfolgeasc bzw.desc:

CriteriaQuery criteriaQuery = criteriaBuilder.createQuery(Foo.class);
Root from = criteriaQuery.from(Foo.class);
CriteriaQuery select = criteriaQuery.select(from);
criteriaQuery.orderBy(criteriaBuilder.asc(from.get("name")),
    criteriaBuilder.desc(from.get("id")));

Die entsprechende SQL-Abfrage wird unten angezeigt:

Hibernate: select foo0_.id as id1_4_, foo0_.name as name2_4_
    from Foo foo0_ order by foo0_.name asc, foo0_.id desc

4. Fazit

In diesem Artikel werden die Sortieralternativen in der Java-Persistenz-API für einfache Entitäten sowie für Entitäten in einer Eins-zu-Viele-Beziehung erläutert. Diese Ansätze delegieren die Last der Sortierarbeit auf die Datenbankschicht.

Die Implementierung dieses JPA-Sortier-Tutorials finden Sie inthe GitHub project - dies ist ein Maven-basiertes Projekt, daher sollte es einfach zu importieren und auszuführen sein.