JPA-kriterieforespørgsler

1. Oversigt

I denne vejledning diskuterer vi en meget nyttig JPA-funktion - Criteria Queries.

Det giver os ikke kun mulighed for at skrive forespørgsler uden at udføre rå SQL, men giver os også en vis objektorienteret kontrol over forespørgslerne, hvilket er et af hovedfunktionerne i dvale. Criteria API giver os mulighed for at opbygge et kriterieforespørgselobjekt programmatisk, hvor vi kan anvende forskellige slags filtreringsregler og logiske forhold.

Siden dvaletilstand 5.2 er Hibernate Criteria API udfaset, og ny udvikling er fokuseret på JPA Criteria API. Vi undersøger, hvordan du bruger dvale og JPA til at opbygge kriterier.

2. Maven-afhængigheder

For at illustrere API'en bruger vi reference-JPA-implementeringen - Hibernate.

For at bruge dvale skal du sørge for at føje den nyeste version af det til din pom.xml fil:

 org. dvale-dvale-kerne 5.3.2.Final 

Den seneste version af dvale kan findes her.

3. Enkelt eksempel ved anvendelse af kriterier

Lad os starte med at se på, hvordan man henter data ved hjælp af kriterier forespørgsler. Vi får et kig på, hvordan man får alle forekomster af en bestemt klasse fra databasen.

Vi har en Vare klasse, der repræsenterer tuplen "VARE" i databasen:

public class Element implementerer Serializable {private Integer itemId; private String itemName; privat strengemne Beskrivelse; privat heltalPris; // standard settere og getters}

Lad os se på et simpelt kriterieforespørgsel, der henter alle rækkerne af “VARE" fra databasen:

Session session = HibernateUtil.getHibernateSession (); CriteriaBuilder cb = session.getCriteriaBuilder (); CriteriaQuery cr = cb.createQuery (Item.class); Rødrod = cr.fra (Item.class); cr.select (rod); Forespørgsel = session.createQuery (cr); Listeresultater = query.getResultList ();

Ovenstående forespørgsel er en simpel demonstration af, hvordan du får alle varerne. Lad os se, hvad der blev gjort, trin for trin:

  1. Opret en forekomst af Session fra SessionFactory objekt
  2. Opret en forekomst af CriteriaBuilder ved at ringe til getCriteriaBuilder () metode
  3. Opret en forekomst af Kriteriespørgsmål ved at ringe til CriteriaBuildercreateQuery () metode
  4. Opret en forekomst af Forespørgsel ved at ringe til SessioncreateQuery () metode
  5. Ring til getResultList () metode til forespørgsel objekt, der giver os resultaterne

Nu hvor vi har dækket det grundlæggende, lad os gå videre til nogle af funktionerne i kriterieforespørgsel:

3.1. Ved brug af Udtryk

Det CriteriaBuilder kan bruges til at begrænse forespørgselsresultater baseret på specifikke forhold. Ved hjælp af KriterierSpørgsmål hvor () metode og give Udtryk lavet af CriteriaBuilder.

Her er nogle eksempler på almindeligt anvendte Udtryk:

Sådan får du varer, der har en pris på mere end 1000:

cr.select (root) .where (cb.gt (root.get ("itemPrice"), 1000));

Dernæst får ting, der har varePris mindre end 1000:

cr.select (root) .where (cb.lt (root.get ("itemPrice"), 1000));

Varer, der har itemNames indeholde Stol:

cr.select (root) .where (cb.like (root.get ("itemName"), "% chair%"));

Optegnelser, der har varePris mellem 100 og 200:

cr.select (root) .where (cb.between (root.get ("itemPrice"), 100, 200));

Sådan kontrolleres, om den givne ejendom er nul:

cr.select (root) .where (cb.isNull (root.get ("itemDescription")));

Sådan kontrolleres, om den givne ejendom ikke er nul:

cr.select (root) .where (cb.isNotNull (root.get ("itemDescription")));

Du kan også bruge metoderne er tom() og isNotEmpty () for at teste, om en Liste inden for en klasse er tom eller ej.

Nu kommer uundgåeligt spørgsmålet, om vi kan kombinere to eller flere af ovenstående sammenligninger eller ej. Svaret er selvfølgelig ja - Criteria API giver os mulighed for let at kæde udtryk:

Predikat [] predikater = nyt predikat [2]; prædikater [0] = cb.isNull (root.get ("itemDescription")); prædikater [1] = cb.like (root.get ("itemName"), "chair%"); cr.select (root) .where (predicates);

Sådan tilføjes to udtryk med logiske operationer:

Forudsig størreThanPrice = cb.gt (root.get ("itemPrice"), 1000); Predikere chairItems = cb.like (root.get ("itemName"), "Chair%");

Elementer med de ovenfor definerede betingelser er forbundet med Logisk ELLER:

cr.select (root) .where (cb.or (greaterThanPrice, chairItems));

For at få varer, der matcher de ovenfor definerede betingelser, forbundet med Logisk OG:

cr.select (root) .where (cb.and (greaterThanPrice, chairItems));

3.2. Sortering

Nu hvor vi kender den grundlæggende brug af Kriterier, lad os se på sorteringsfunktionaliteten af Kriterier.

I det følgende eksempel bestiller vi listen i stigende rækkefølge efter navnet og derefter i faldende rækkefølge af prisen:

cr.orderBy (cb.asc (root.get ("itemName")), cb.desc (root.get ("itemPrice")));

I det næste afsnit vil vi se på, hvordan man udfører samlede funktioner.

3.3. Fremskrivninger, aggregater og grupperingsfunktioner

Indtil videre har vi dækket de fleste af de grundlæggende emner. Lad os nu se på de forskellige samlede funktioner:

Få rækkeantal:

CriteriaQuery cr = cb.createQuery (Long.class); Rotrod = cr.fra (Item.class); cr.select (cb.count (root)); Forespørgsel = session.createQuery (cr); Liste itemProjected = query.getResultList ();

Følgende er et eksempel på samlede funktioner:

Samlet funktion til Gennemsnit:

CriteriaQuery cr = cb.createQuery (Double.class); Rødrod = cr.fra (Item.class); cr.select (cb.avg (root.get ("itemPrice"))); Forespørgsel = session.createQuery (cr); Liste over avgItemPriceList = query.getResultList ();

Andre nyttige samlede metoder, der er tilgængelige, er sum(), maks (), min (), tælle() etc.

3.4. Kriterier Opdatering

Fra JPA 2.1 understøttes der udførelse af databaseopdateringer ved hjælp af Kriterier API.

Kriterier Opdatering har en sæt() metode, der kan bruges til at give nye værdier til databaseposter:

CriteriaUpdate criteriaUpdate = cb.createCriteriaUpdate (Item.class); Root root = criteriaUpdate.from (Item.class); criteriaUpdate.set ("itemPrice", newPrice); criteriaUpdate.where (cb.equal (root.get ("itemPrice"), oldPrice)); Transaktionstransaktion = session.beginTransaction (); session.createQuery (criteriaUpdate) .executeUpdate (); transaktion.forpligtelse ();

I ovenstående uddrag opretter vi en forekomst af Kriterier Opdatering fra CriteriaBuilder og brug dens sæt() metode til at give nye værdier til varePris. For at opdatere flere egenskaber skal vi bare ringe til sæt() metode flere gange.

3.5. Kriterier Slet

Kriterier Slet, som navnet antyder, muliggør en sletning ved hjælp af Kriterier API. Alt, hvad vi har brug for, er at oprette en forekomst af Kriterier Slet og brug hvor() metode til at anvende begrænsninger:

CriteriaDelete criteriaDelete = cb.createCriteriaDelete (Item.class); Root root = criteriaDelete.from (Item.class); criteriaDelete.where (cb.greaterThan (root.get ("itemPrice"), targetPrice)); Transaktionstransaktion = session.beginTransaction (); session.createQuery (criteriaDelete) .executeUpdate (); transaktion.forpligtelse ();

4. Fordel over HQL

I de foregående afsnit har vi dækket, hvordan man bruger kriterier forespørgsler.

Klart, den største og mest hårdtslående fordel ved Criteria-forespørgsler i forhold til HQL er den pæne, rene, Objektorienterede API.

Vi kan simpelthen skrive mere fleksible, dynamiske forespørgsler sammenlignet med almindelig HQL. Logikken kan refaktoriseres med IDE og har alle typesikkerhedsfordelene ved selve Java-sproget.

Der er naturligvis også nogle ulemper, især omkring mere komplekse sammenføjninger.

Så generelt set bliver vi nødt til at bruge det bedste værktøj til jobbet - det kan være Criteria API i de fleste tilfælde, men der er bestemt tilfælde, hvor vi bliver nødt til at gå lavere niveau.

5. Konklusion

I denne artikel fokuserede vi på det grundlæggende i Criteria Queries in Hibernate og JPA og også på nogle af de avancerede funktioner i API'en.

Koden, der diskuteres her, er tilgængelig i Github-arkivet.