Dotazy na kritériá JPA

1. Prehľad

V tomto výučbe sa budeme venovať veľmi užitočnej funkcii JPA - Criteria Queries.

Umožňuje nám to nielen písať dotazy bez vykonávania nespracovaného kódu SQL, ale poskytuje nám aj určitú objektovo orientovanú kontrolu nad dotazmi, ktorá je jednou z hlavných funkcií režimu dlhodobého spánku. Criteria API nám umožňuje programovo vytvoriť objekt dotazu na kritériá, kde môžeme použiť rôzne druhy pravidiel filtrácie a logické podmienky.

Od verzie Hibernate 5.2 je rozhranie Hibernate Criteria API zastarané a nový vývoj sa zameriava na rozhranie API JPA Criteria. Preskúmame, ako použiť Hibernate a JPA na zostavenie kritérií.

2. Maven závislosti

Na ilustráciu API použijeme referenčnú implementáciu JPA - Hibernate.

Ak chcete používať režim dlhodobého spánku, nezabudnite do svojho počítača pridať najnovšiu verziu pom.xml spis:

 org.hibernate hibernate-core 5.3.2.Final 

Najnovšiu verziu režimu dlhodobého spánku nájdete tu.

3. Jednoduchý príklad použitia kritérií

Začnime tým, ako sa dozvieme, ako načítať údaje pomocou dotazov Kritériá. Pozrime sa, ako z databázy získať všetky inštancie konkrétnej triedy.

Máme Položka trieda, ktorá predstavuje n-ticu „ITEM“ v databáze:

verejná trieda Položka implementuje Serializable {private Integer itemId; private String itemName; private String itemDescription; private integer itemPrice; // štandardní zakladatelia a obstarávatelia}

Pozrime sa na jednoduchý dotaz na kritériá, ktorý získa všetky riadky „POLOŽKA “ z databázy:

Relácia relácie = HibernateUtil.getHibernateSession (); CriteriaBuilder cb = session.getCriteriaBuilder (); CriteriaQuery cr = cb.createQuery (Item.class); Koreňový koreň = cr.from (Item.class); cr.select (koreň); Dotaz na dopyt = session.createQuery (cr); Zoznam výsledkov = query.getResultList ();

Vyššie uvedený dotaz je jednoduchou ukážkou toho, ako získať všetky položky. Pozrime sa, čo sa stalo, krok za krokom:

  1. Vytvorte inštanciu Session z SessionFactory objekt
  2. Vytvorte inštanciu C.riteriaBuilder zavolaním na getCriteriaBuilder () metóda
  3. Vytvorte inštanciu CriteriaQuery zavolaním na CriteriaBuildermetóda createQuery ()
  4. Vytvorte inštanciu Dopyt zavolaním na SessioncreateQuery () metóda
  5. Zavolajte getResultList () metóda dopyt objekt, ktorý nám dáva výsledky

Teraz, keď sme prebrali základné informácie, prejdime k niektorým funkciám dotazu na kritériá:

3.1. Použitím Výrazy

The CriteriaBuilder možno použiť na obmedzenie výsledkov dotazu na základe konkrétnych podmienok. Používaním CriteriaQuery where () metóda a zabezpečiť Výrazy vytvoril CriteriaBuilder.

Tu uvádzam niekoľko príkladov bežne používaných Výrazy:

Postup získania položiek s cenou vyššou ako 1 000:

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

Ďalej získavanie položiek itemPrice menej ako 1 000:

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

Položky majú Názvy položiek obsahovať Stolička:

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

Záznamy majú itemPrice medzi 100 a 200:

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

Ak chcete skontrolovať, či je daná vlastnosť nulová:

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

Ak chcete skontrolovať, či daná vlastnosť nie je nulová:

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

Môžete tiež použiť metódy je prázdny() a isNotEmpty () vyskúšať, či a Zoznam v rámci triedy je prázdny alebo nie.

Teraz nevyhnutne prichádza otázka, či môžeme spojiť dve alebo viac z vyššie uvedených porovnaní alebo nie. Odpoveď je samozrejme áno - Criteria API nám umožňuje ľahko reťaziť výrazy:

Predikát [] predikáty = nový Predikát [2]; predikáty [0] = cb.isNull (root.get ("itemDescription")); predikáty [1] = cb.like (root.get ("itemName"), "chair%"); cr.select (root). kde (predikáty);

Ak chcete pridať dva výrazy pomocou logických operácií:

Predikát greaterThanPrice = cb.gt (root.get ("itemPrice"), 1000); Predikát chairItems = cb.like (root.get ("itemName"), "Chair%");

Položky s vyššie definovanými podmienkami spojené s Logické ALEBO:

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

Ak chcete získať položky, ktoré zodpovedajú vyššie definovaným podmienkam, spojené s Logické AND:

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

3.2. Triedenie

Teraz, keď poznáme základné použitie Kritériá, pozrime sa na funkcionalitu triedenia Kritériá.

V nasledujúcom príklade zoradíme zoznam vo vzostupnom poradí podľa názvu a potom v zostupnom poradí podľa ceny:

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

V nasledujúcej časti sa pozrieme na to, ako robiť agregačné funkcie.

3.3. Projekcie, agregáty a zoskupovacie funkcie

Doteraz sme prebrali väčšinu základných tém. Teraz sa pozrime na rôzne agregačné funkcie:

Získať počet riadkov:

CriteriaQuery cr = cb.createQuery (Long.class); Koreňový koreň = cr.from (Item.class); cr.select (cb.count (root)); Dotaz na dopyt = session.createQuery (cr); Zoznam itemProjected = query.getResultList ();

Nasleduje príklad agregačných funkcií:

Agregát funkcia pre Priemerná:

CriteriaQuery cr = cb.createQuery (Double.class); Koreňový koreň = cr.from (Item.class); cr.select (cb.avg (root.get ("itemPrice"))); Dotaz na dopyt = session.createQuery (cr); Zoznam avgItemPriceList = query.getResultList ();

Ďalšie užitočné agregačné metódy, ktoré sú k dispozícii, sú suma (), max (), min (), count () atď.

3.4. CriteriaUpdate

Počnúc JPA 2.1 existuje podpora pre vykonávanie aktualizácií databázy pomocou Kritériá API.

CriteriaUpdatesada () metóda, ktorá sa dá použiť na poskytnutie nových hodnôt pre databázové záznamy:

CriteriaUpdate criteriaUpdate = cb.createCriteriaUpdate (Item.class); Root root = criteriaUpdate.from (Item.class); kritériaUpdate.set ("itemPrice", newPrice); riteriaUpdate.where (cb.equal (root.get ("itemPrice"), oldPrice)); Transakčná transakcia = session.beginTransaction (); session.createQuery (criteriaUpdate) .executeUpdate (); transaction.commit ();

Vo vyššie uvedenom úryvku vytvoríme inštanciu CriteriaUpdate z CriteriaBuilder a používať jeho sada () metóda na zabezpečenie nových hodnôt pre itemPrice. Ak chcete aktualizovať viac vlastností, musíme zavolať na sada () metóda viackrát.

3.5. CriteriaDelete

Kritériá Odstrániť ako už z jeho názvu vyplýva, umožňuje operáciu mazania pomocou Kritériá API. Všetko, čo potrebujeme, je vytvoriť inštanciu CriteriaDelete a použite kde() spôsob uplatňovania obmedzení:

CriteriaDelete kritériaDelete = cb.createCriteriaDelete (Položka.trieda); Root root = criteriaDelete.from (Item.class); riteriaDelete.where (cb.greaterThan (root.get ("itemPrice"), targetPrice)); Transakčná transakcia = session.beginTransaction (); session.createQuery (criteriaDelete) .executeUpdate (); transaction.commit ();

4. Výhoda oproti HQL

V predchádzajúcich častiach sme sa venovali používaniu kritérií podľa kritérií.

Jasne, hlavnou a najpálčivejšou výhodou dotazov Criteria oproti HQL je pekné, čisté, objektovo orientované API.

V porovnaní s obyčajným HQL môžeme jednoducho napísať flexibilnejšie a dynamickejšie dotazy. Logiku je možné refaktorizovať pomocou IDE a má všetky výhody bezpečnosti typu samotného jazyka Java.

Existujú samozrejme aj niektoré nevýhody, najmä pri zložitejších spojeniach.

Všeobecne povedané, budeme musieť na prácu použiť ten najlepší nástroj - vo väčšine prípadov to môže byť API Criteria, ale určite existujú prípady, keď budeme musieť ísť na nižšiu úroveň.

5. Záver

V tomto článku sme sa zamerali na základy Criteria Queries v režimoch Hibernate a JPA a tiež na niektoré pokročilé funkcie API.

Tu diskutovaný kód je k dispozícii v úložisku Github.