Typy dotazov JPA

1. Prehľad

V tomto tutoriáli si rozoberieme rôzne typy dotazov JPA. Ďalej sa zameriame na porovnanie rozdielov medzi nimi a na rozšírenie kladov a záporov každého z nich.

2. Inštalácia

Najskôr definujme UserEntity triedy, ktorú použijeme pre všetky príklady v tomto článku:

@Table (name = "users") @Entity public class UserEntity {@Id private Long id; súkromné ​​meno reťazca; // Štandardný konštruktor, getre a setre. }

Existujú tri základné typy dotazov JPA:

  • Dopyt, napísaný v syntaxi Java Persistence Query Language (JPQL)
  • NativeQuery, napísané jednoduchou syntaxou SQL
  • Criteria API Query, zostavené programovo pomocou rôznych metód

Poďme ich preskúmať.

3. Dopyt

A Dopyt má podobnú syntax ako SQL a všeobecne sa používa na vykonávanie operácií CRUD:

public UserEntity getUserByIdWithPlainQuery (Long id) {Query jpqlQuery = getEntityManager (). createQuery ("SELECT u FROM UserEntity u WHERE u.id =: id"); jpqlQuery.setParameter ("id", id); return (UserEntity) jpqlQuery.getSingleResult (); }

Toto Dopyt získa zodpovedajúci záznam z používateľov tabuľky a tiež ju mapuje na UserEntity objekt.

Existujú dve ďalšie Dopyt podtypy:

  • TypedQuery
  • NamedQuery

Uvidíme ich v akcii.

3.1. TypedQuery

Musíme venovať pozornosť návrat vyhlásenie v našom predchádzajúcom príklade. JPA nemôže odvodiť, čo Dopyt Výsledný typ bude, a ako výsledok budeme musieť obsadiť.

Ale, JPA poskytuje špeciál Dopyt subtyp známy ako a TypedQuery.Toto je vždy preferované, ak vieme svoje Dopyt typ výsledku vopred. Vďaka tomu je náš kód oveľa spoľahlivejší a ľahšie testovateľný.

Pozrime sa a TypedQuery alternatíva v porovnaní s našim prvým príkladom:

public UserEntity getUserByIdWithTypedQuery (Long id) {TypedQuery typedQuery = getEntityManager (). createQuery ("SELECT u FROM UserEntity u WHERE u.id =: id", UserEntity.class); typedQuery.setParameter ("id", id); návrat typedQuery.getSingleResult (); }

Tadiaľto, Zadarmo máme silnejšie písanie, vyhnúť sa možným výnimkám.

3.2. NamedQuery

Aj keď môžeme dynamicky definovať a Dopyt na konkrétnych metódach môžu nakoniec prerásť do ťažko udržiavateľného kódového základu. Čo ak by sme mohli dotazy na všeobecné použitie uchovávať na jednom centralizovanom a ľahko čitateľnom mieste?

Spoločné parlamentné zhromaždenia nás v tejto veci tiež pokryli iným Dopyt subtyp známy ako a NamedQuery.

Definujeme NamedQuery na Subjekt triedy, ktorá poskytuje centralizovaný, rýchly a ľahký spôsob čítania a hľadania SubjektSúvisiace otázky.

Všetky NamedQueries musí mať jedinečný názov.

Pozrime sa, ako môžeme pridať a NamedQuery k nášmu UserEntity trieda:

@Table (name = "users") @Entity @NamedQuery (name = "UserEntity.findByUserId", query = "SELECT u FROM UserEntity u WHERE u.id =: userId") verejná trieda UserEntity {@Id private Long id; súkromné ​​meno reťazca; // Štandardný konštruktor, getre a setre. }

The @NamedQuery anotácia musí byť zoskupená do a @NamedQueries anotácia, ak používame Java pred verziou 8. Od verzie Java 8 môžeme jednoducho opakovať @NamedQuery anotácia na našu Subjekt trieda.

Pomocou a NamedQuery je veľmi jednoduché:

public UserEntity getUserByIdWithNamedQuery (Long id) {Dotaz namedQuery = getEntityManager (). createNamedQuery ("UserEntity.findByUserId"); namedQuery.setParameter ("userId", id); return (UserEntity) namedQuery.getSingleResult (); }

4. NativeQuery

A NativeQuery je jednoducho dotaz SQL. Tie nám umožňujú uvoľniť plný výkon našej databázy, pretože môžeme používať proprietárne funkcie, ktoré nie sú dostupné v syntaxi s obmedzením JPQL.

To má svoju cenu. Stratíme prenosnosť databázy našej aplikácie s NativeQuery pretože náš poskytovateľ JPA už nemôže získavať konkrétne podrobnosti z implementácie databázy alebo od dodávateľa.

Pozrime sa, ako používať a NativeQuery ktoré poskytujú rovnaké výsledky ako naše predchádzajúce príklady:

public UserEntity getUserByIdWithNativeQuery (Long id) {Query nativeQuery = getEntityManager (). createNativeQuery ("SELECT * FROM users WHERE id =: userId", UserEntity.class); nativeQuery.setParameter ("userId", id); return (UserEntity) nativeQuery.getSingleResult (); }

Vždy musíme zvážiť, či a NativeQuery je jediná možnosť. Väčšinou dobrý JPQL Dopyt môže splniť naše potreby a čo je najdôležitejšie, udržiavať úroveň abstrakcie od skutočnej implementácie databázy.

Použitím NativeQuery nemusí to nevyhnutne znamenať, že sa uzamkneme k jednému konkrétnemu predajcovi databázy. Nakoniec, ak naše dotazy nepoužívajú proprietárne príkazy SQL a používajú iba štandardnú syntax SQL, nemalo by to robiť problém s prepínaním poskytovateľov.

5. Kritériá API Query

Kritériá Dotazy API sú programovo zostavené, typovo bezpečné dotazy - trochu podobné syntaxe dotazov JPQL:

public UserEntity getUserByIdWithCriteriaQuery (dlhé ID) {CriteriaBuilder kritériaBuilder = getEntityManager (). getCriteriaBuilder (); CriteriaQuery kritériáQuery = kritériaBuilder.createQuery (UserEntity.class); Root userRoot = criteriaQuery.from (UserEntity.class); UserEntity queryResult = getEntityManager (). CreateQuery (criteriaQuery.select (userRoot) .where (criteriaBuilder.equal (userRoot.get ("id"), id)))) .getSingleResult (); návrat queryResult; }

Môže to byť skľučujúce použiť Kritériá Dotazy na API z prvej ruky, ale môžu byť skvelou voľbou, keď potrebujeme pridať prvky dynamického dotazu, alebo keď ich spojíme s JPA Metamodel.

6. Záver

V tomto rýchlom článku sme sa dozvedeli, čo sú dotazy JPA, spolu s ich využitím.

JPA dotazy sú skvelým spôsobom, ako abstrahovať našu obchodnú logiku z našej vrstvy prístupu k údajom, pretože sa môžeme spoľahnúť na syntax JPQL a nechať nášho poskytovateľa JPA, ktorý si vyberie, spracovať Dopyt preklad.

Celý kód uvedený v tomto článku je k dispozícii na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found