Upiti o kriterijima JPA

1. Pregled

U ovom uputstvu razgovarat ćemo o vrlo korisnoj značajci JPA - kriterijima upita.

Ne samo da nam omogućuje pisanje upita bez potrebe za neobrađenim SQL-om, već nam daje i objektno orijentiranu kontrolu nad upitima, što je jedna od glavnih značajki hibernacije. API kriterija omogućuje nam programsku izgradnju objekta upita kriterija, gdje možemo primijeniti različite vrste pravila filtriranja i logičke uvjete.

Od Hibernate 5.2, Hibernate Criteria API je zastario i novi razvoj usmjeren je na JPA Criteria API. Istražit ćemo kako koristiti Hibernate i JPA za izgradnju kriterija upita.

2. Ovisnosti Mavena

Da bismo ilustrirali API, poslužit ćemo se referentnom JPA implementacijom - Hibernate.

Da biste koristili Hibernate, dodajte mu najnoviju verziju pom.xml datoteka:

 org.hibernate hibernate-core 5.3.2.Final 

Najnoviju verziju hibernacije možete pronaći ovdje.

3. Jednostavni primjer korištenja kriterija

Započnimo s istraživanjem kako dohvatiti podatke pomoću upita kriterija. Imat ćemo kako iz baze podataka dobiti sve instance određene klase.

Mi imamo Artikal klasa koja predstavlja korijen "ARTIKAL" u bazi podataka:

stavka javne klase implementira Serializable {private Integer itemId; private String itemName; private String itemDescription; private Integer itemPrice; // standardni postavljači i dobivači}

Pogledajmo jednostavan upit s kriterijima koji će dohvatiti sve retke "ARTIKAL" iz baze podataka:

Sjednica sesije = HibernateUtil.getHibernateSession (); CriteriaBuilder cb = session.getCriteriaBuilder (); CriteriaQuery cr = cb.createQuery (Item.class); Korijen korijena = cr.from (Item.class); cr.select (root); Upit upita = session.createQuery (cr); Popis rezultata = query.getResultList ();

Gornji je upit jednostavna demonstracija kako doći do svih predmeta. Pogledajmo što je učinjeno, korak po korak:

  1. Stvorite instancu Sjednica od SjednicaTvornica objekt
  2. Stvorite instancu CriteriaBuilder pozivom na getCriteriaBuilder () metoda
  3. Stvorite instancu KriterijiPitanje pozivom na CriteriaBuildercreateQuery () metoda
  4. Stvorite instancu Upit pozivom na SjednicacreateQuery () metoda
  5. Nazovite getResultList () metoda upit objekt koji nam daje rezultate

Sad kad smo pokrili osnove, prijeđimo na neke značajke upita kriterija:

3.1. Koristeći Izrazi

The CriteriaBuilder može se koristiti za ograničavanje rezultata upita na temelju određenih uvjeta. Pomoću CriteriaQuery where () metoda i pružiti Izrazi napravio CriteriaBuilder.

Evo nekoliko primjera najčešće korištenih Izrazi:

Da biste dobili predmete čija je cijena veća od 1000:

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

Dalje, dobivanje predmeta koji imaju itemPrice manje od 1000:

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

Predmeti koji imaju itemNames sadrže Stolica:

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

Zapisi koji imaju itemPrice između 100 i 200:

cr.select (root) .where (cb.između (root.get ("itemPrice"), 100, 200));

Da biste provjerili je li dato svojstvo null:

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

Da biste provjerili nije li dato svojstvo null:

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

Također možete koristiti metode prazno je() i isNotEmpty () testirati je li Popis u razredu je prazan ili nije.

Sada se neizbježno postavlja pitanje možemo li kombinirati dvije ili više gore navedenih usporedbi ili ne. Odgovor je, naravno, da - API kriterija omogućuje nam lako povezivanje izraza:

Predikat [] predikati = novi predikat [2]; predikati [0] = cb.isNull (root.get ("itemDescription")); predikati [1] = cb.like (root.get ("itemName"), "chair%"); cr.select (root) .where (predikati);

Da biste dodali dva izraza s logičkim operacijama:

Predikat većeThanPrice = cb.gt (root.get ("itemPrice"), 1000); Predikat stolItems = cb.like (root.get ("itemName"), "Chair%");

Stavke s gore definiranim uvjetima spojene sa Logično ILI:

cr.select (root) .where (cb.or (većeTanPrice, stolItemtem));

Da biste dobili stavke koje se podudaraju s gore definiranim uvjetima, pridružene Logično I:

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

3.2. Sortiranje

Sada kada znamo osnovnu uporabu Kriteriji, pogledajmo funkcionalnosti sortiranja Kriteriji.

U sljedećem primjeru popis naređujemo uzlaznim redoslijedom imena, a zatim silaznim redoslijedom cijene:

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

U sljedećem ćemo odjeljku pogledati kako izvršavati skupne funkcije.

3.3. Projekcije, agregati i funkcije grupiranja

Do sada smo obradili većinu osnovnih tema. Sada ćemo pogledati različite agregatne funkcije:

Dohvati broj redaka:

CriteriaQuery cr = cb.createQuery (Long.class); Korijen korijena = cr.from (Item.class); cr.select (cb.count (root)); Upit upita = session.createQuery (cr); Lista stavkiProjected = query.getResultList ();

Slijedi primjer agregatnih funkcija:

Zbirno funkcija za Prosječno:

CriteriaQuery cr = cb.createQuery (Double.class); Korijen korijena = cr.from (Item.class); cr.select (cb.avg (root.get ("itemPrice"))); Upit upita = session.createQuery (cr); Popis avgItemPriceList = query.getResultList ();

Ostale korisne agregatne metode koje su dostupne su iznos(), maks. (), min (), računati() itd.

3.4. CriteriaUpdate

Počevši od JPA 2.1, postoji podrška za izvođenje ažuriranja baze podataka pomoću Kriteriji API.

CriteriaUpdate ima postavi () metoda koja se može koristiti za pružanje novih vrijednosti za zapise baze podataka:

CriteriaUpdate criteriaUpdate = cb.createCriteriaUpdate (Item.class); Korijen korijena = kriterijiUpdate.from (Item.class); criteriaUpdate.set ("itemPrice", newPrice); criteriaUpdate.where (cb.equal (root.get ("itemPrice"), oldPrice)); Transakcijska transakcija = session.beginTransaction (); session.createQuery (criteriaUpdate) .executeUpdate (); transakcija.commit ();

U gornjem isječku stvaramo primjerak CriteriaUpdate od CriteriaBuilder i koristiti svoje postavi () metoda za pružanje novih vrijednosti za itemPrice. Da bismo ažurirali više svojstava, samo moramo nazvati postavi () metoda više puta.

3.5. CriteriaDelete

CriteriaDelete, kako mu samo ime govori, omogućuje operaciju brisanja pomoću Kriteriji API. Sve što trebamo je stvoriti primjerak CriteriaDelete i koristite gdje() metoda primjene ograničenja:

CriteriaDelete criteriaDelete = cb.createCriteriaDelete (Item.class); Korijen korijena = kriterijiDelete.from (Item.class); criteriaDelete.where (cb.greaterThan (root.get ("itemPrice"), targetPrice)); Transakcijska transakcija = session.beginTransaction (); session.createQuery (kriterijiDelete) .executeUpdate (); transakcija.commit ();

4. Prednost nad HQL-om

U prethodnim odjeljcima govorili smo o korištenju upita s kriterijima.

Jasno, glavna i najozbiljnija prednost upita kriterija u odnosu na HQL je lijep, čist, objektno orijentirani API.

Jednostavno možemo pisati fleksibilnije, dinamičke upite u usporedbi s običnim HQL-om. Logika se može refaktorirati s IDE-om i ima sve prednosti tipične sigurnosti samog jezika Java.

Postoje, naravno, i neki nedostaci, posebno oko složenijih spajanja.

Dakle, općenito govoreći, morat ćemo koristiti najbolji alat za posao - to u većini slučajeva može biti API kriterija, ali definitivno postoje slučajevi u kojima ćemo morati ići na nižu razinu.

5. Zaključak

U ovom smo se članku usredotočili na osnove kriterija upita u hibernaciji i JPA, kao i na neke napredne značajke API-ja.

Ovdje raspravljeni kod dostupan je u spremištu Github.