Sortering med JPA

1. Oversigt

Denne artikel illustrerer de forskellige måder JPA kan bruges til sortering.

2. Sortering med JPA / JQL API

Brug af JQL til at sortere sker ved hjælp af Bestil efter klausul:

String jql; Forespørgsel = entityManager.createQuery (jql);

Baseret på denne forespørgsel genererer JPA følgende ligeud SQL-sætning:

Dvaletilstand: vælg foo0_.id som id1_4_, foo0_.name som navn2_4_ fra Foo foo0_ rækkefølge efter foo0_.id

Bemærk, at SQL-nøgleordene i JQL-strengen ikke er store og små bogstaver, men navnene på enhederne og deres attributter er.

2.1. Indstilling af sorteringsrækkefølgen

Som standard sorteringsrækkefølgen stiger, men det kan udtrykkeligt indstilles i JQL-strengen. Ligesom i ren SQL er bestillingsmulighederne asc og beskrivelse:

String jql = "Vælg f fra Foo som f rækkefølge efter f.id desc"; Forespørgsel sortQuery = entityManager.createQuery (jql);

Det genereret SQL-forespørgsel vil derefter inkludere ordreretningen:

Dvaletilstand: vælg foo0_.id som id1_4_, foo0_.name som navn2_4_ fra Foo foo0_ rækkefølge efter foo0_.id desc

2.2. Sortering efter mere end en attribut

For at sortere efter flere attributter føjes disse til order forbi klausul om JQL-strengen:

String jql; Forespørgsel sortQuery = entityManager.createQuery (jql);

Begge sorteringsbetingelser vises i genereret SQL-forespørgsel udmelding:

Dvaletilstand: vælg foo0_.id som id1_4_, foo0_.name som navn2_4_ fra Foo foo0_ rækkefølge efter foo0_.name asc, foo0_.id desc

2.3. Indstilling af sorteringspræference for nulværdier

Standardprioriteten for nuller er databasespecifik, men dette kan tilpasses via NULLS FØRST eller NULLS SIDSTE klausul i HQL-forespørgselsstrengen.

Her er et simpelt eksempel - bestilling efter navn af Foo i faldende rækkefølge og placering Nuls i slutningen:

Query sortQuery = entityManager.createQuery ("Vælg f fra Foo som f rækkefølge efter f.name desc NULLS SIDSTE");

SQL-forespørgslen, der genereres, inkluderer er nul 1 anden 0 slutklausul (3. linje):

Dvaletilstand: vælg foo0_.id som id1_4_, foo0_.BAR_ID som BAR_ID2_4_, foo0_.bar_Id som bar_Id2_4_, foo0_.name som navn3_4_, fra Foo foo0_ rækkefølge efter sag, når foo0_.name er ugyldigt, så 1 andet 0 end, foo

2.4. Sorterer en til mange forhold

Gå forbi de grundlæggende eksempler, lad os nu se på en brugssag, der involverer sortering af enheder i forholdet en til mangeBar indeholdende en samling af Foo enheder.

Vi vil sortere Bar enheder og også deres samling af Foo enheder - JPA er især enkel til denne opgave:

  1. Sortering af samlingen: Tilføj en Bestil af kommentar forud for Foo samling i Bar enhed:
    @OrderBy ("navn ASC") Liste fooList;
  2. Sortering af den enhed, der indeholder samlingen:
    String jql = "Vælg b fra bjælke som b rækkefølge efter b.id"; Forespørgsel barQuery = entityManager.createQuery (jql); Liste barList = barQuery.getResultList ();

Bemærk, at @OrderBy kommentar er valgfri, men vi bruger den i dette tilfælde, fordi vi vil sortere Foo samling af hver Bar.

Lad os se på SQL-forespørgsel sendt til RDMS:

Dvaletilstand: vælg bar0_.id som id1_0_, bar0_.name som navn2_0_ fra Bar bar0_ rækkefølge efter bar0_.id Dvaletilstand: vælg foolist0_.BAR_ID som BAR_ID2_0_0_, foolist0_.id som id1_4_0_, narrist0_.id som id1_4____ID_AR_ID_AR_ID .bar_Id som bar_Id2_4_1_, foolist0_.name som navn3_4_1_ fra Foo foolist0_ hvor foolist0_.BAR_ID =? rækkefølge efter foolist0_.name asc 

Den første forespørgsel sorterer forældrene Bar enhed. Den anden forespørgsel genereres for at sortere samlingen af ​​barnet Foo enheder, der hører til Bar.

3. Sortering med JPA Criteria Query Object API

Med JPA-kriterier - rækkefølge metoden er et "one stop" alternativ til at indstille alle sorteringsparametre: både ordreretning og attributter at sortere ved kan indstilles. Følgende er metodens API:

  • rækkefølge(CriteriaBuilder.asc): Sorterer i stigende rækkefølge.
  • rækkefølge(CriteriaBuilder.desc): Sorterer i faldende rækkefølge.

Hver Bestille forekomst oprettes med CriteriaBuilder objekt gennem sin asc eller beskrivelse metoder.

Her er et hurtigt eksempel - sortering Foos af deres navn:

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

Argumentet til get-metoden er store og små bogstaver, da den skal matche navnet på attributten.

I modsætning til simpel JQL er JPA Criteria Query Object API tvinger en eksplicit ordreretning i forespørgslen. Bemærk i den sidste linje i dette kodestykke, at criteriaBuilder objekt angiver den sorteringsrækkefølge, der skal stige, ved at kalde dens asc metode.

Når ovenstående kode udføres, genererer JPA SQL-forespørgslen vist nedenfor. JPA Criteria Object genererer en SQL-sætning med en eksplicit asc klausul:

Dvaletilstand: vælg foo0_.id som id1_4_, foo0_.name som navn2_4_ fra Foo foo0_ rækkefølge efter foo0_.name asc

3.1. Sortering efter mere end en attribut

For at sortere efter mere end en attribut skal du blot videregive en Bestille eksempel til rækkefølge metode for hver attribut, der skal sorteres efter.

Her er et hurtigt eksempel - sortering efter navn og id, i asc og beskrivelse rækkefølge henholdsvis:

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

Den tilsvarende SQL-forespørgsel er vist nedenfor:

Dvaletilstand: vælg foo0_.id som id1_4_, foo0_.name som navn2_4_ fra Foo foo0_ rækkefølge efter foo0_.name asc, foo0_.id desc

4. Konklusion

Denne artikel udforsker sorteringsalternativerne i Java Persistence API for enkle enheder såvel som for enheder i en-til-mange-relation. Disse tilgange delegerer byrden ved sorteringsarbejdet til databaselaget.

Implementeringen af ​​denne JPA-sorteringsvejledning kan findes i GitHub-projektet - dette er et Maven-baseret projekt, så det skal være let at importere og køre som det er.