Vrste JPA upita

1. Pregled

U ovom uputstvu razgovarat ćemo o različitim vrstama JPA upita. Štoviše, usredotočit ćemo se na usporedbu razlika između njih i šireći na sve prednosti i nedostatke.

2. Postavljanje

Prvo, definirajmo UserEntity klase koju ćemo koristiti za sve primjere u ovom članku:

@Tabela (name = "users") @Entity javna klasa UserEntity {@Id private Long id; privatni naziv niza; // Standardni konstruktor, geteri i postavljači. }

Postoje tri osnovne vrste JPA upita:

  • Upit, napisano u sintaksi Java Persistence Query Language (JPQL)
  • NativeQuery, napisan u običnoj SQL sintaksi
  • Upit za API kriterija, konstruiran programski putem različitih metoda

Istražimo ih.

3. Upit

A Upit je u sintaksi sličan SQL-u i obično se koristi za izvođenje CRUD operacija:

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 (); }

Ovaj Upit dohvaća odgovarajući zapis iz datoteke korisnika tablici i također je preslikava na UserEntity objekt.

Dvije su dodatne Upit podvrste:

  • TypedQuery
  • NamedQuery

Pogledajmo ih na djelu.

3.1. TypedQuery

Moramo obratiti pažnju na povratak izjava u našem prethodnom primjeru. JPA ne može utvrditi što Upit vrsta rezultata bit će i, kao rezultat toga, moramo emitirati.

Ali, JPA pruža posebnu Upit podvrsta poznata kao a TypedQuery.To je uvijek poželjno ako znamo svoje Upit tip rezultata prethodno. Uz to, čini naš kod mnogo pouzdanijim i lakšim za testiranje.

Da vidimo a TypedQuery alternativa, u usporedbi s našim prvim primjerom:

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

Ovuda, dobivamo jače tipkanje besplatno, izbjegavajući moguće izuzeće pri lijevanju.

3.2. NamedQuery

Iako možemo dinamički definirati a Upit na određenim metodama mogu na kraju prerasti u bazu koda koju je teško održavati. Što ako opće upite o upotrebi možemo zadržati na jednom centraliziranom mjestu koje se lako čita?

JPA nas je također pokrio s tim drugim Upit podvrsta poznata kao a NamedQuery.

Mi definiramo NamedQuery na Entitet klase, pružajući centraliziran, brz i jednostavan način čitanja i pronalaženja EntitetSrodni upiti.

svi NamedQueries mora imati jedinstveno ime.

Pogledajmo kako možemo dodati a NamedQuery našem UserEntity razred:

@Table (name = "users") @Entity @NamedQuery (name = "UserEntity.findByUserId", query = "SELECT u FROM UserEntity u WHERE u.id =: userId") javna klasa UserEntity {@Id private Long id; privatni naziv niza; // Standardni konstruktor, geteri i postavljači. }

The @NamedQuery napomena mora biti grupirana unutar a @NamedQueries napomena ako koristimo Javu prije verzije 8. Od Jave 8 dalje možemo jednostavno ponoviti @NamedQuery napomena na našem Entitet razred.

Korištenje a NamedQuery je vrlo jednostavno:

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

4. NativeQuery

A NativeQuery je jednostavno SQL upit. Oni nam omogućuju da oslobodimo svu snagu naše baze podataka, jer možemo koristiti zaštićene značajke koje nisu dostupne u sintaksi ograničenoj na JPQL.

To se plaća. Gubimo prenosivost baze podataka naše aplikacije s NativeQuery jer naš pružatelj JPA više ne može apstrahirati određene detalje iz implementacije baze podataka ili dobavljača.

Pogledajmo kako koristiti a NativeQuery koji daje iste rezultate kao i naši prethodni primjeri:

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 (); }

Uvijek moramo uzeti u obzir ako a NativeQuery je jedina opcija. Većinu vremena dobar JPQL Upit mogu ispuniti naše potrebe i što je najvažnije, održati razinu apstrakcije od stvarne implementacije baze podataka.

Koristeći NativeQuery ne znači nužno da se zatvorimo za određenog dobavljača baze podataka. Napokon, ako naši upiti ne koriste zaštićene SQL naredbe i koriste samo standardnu ​​SQL sintaksu, zamjena davatelja usluga ne bi trebala predstavljati problem.

5. Kriteriji API upit

Kriteriji API upiti su programski izgrađeni, tipski sigurni upiti - donekle slični JPQL upitima u sintaksi:

javni UserEntity getUserByIdWithCriteriaQuery (dugi id) {CriteriaBuilder criteriaBuilder = getEntityManager (). getCriteriaBuilder (); CriteriaQuery criteriaQuery = criteriaBuilder.createQuery (UserEntity.class); Korijeni userRoot = kriterijiQuery.from (UserEntity.class); UserEntity queryResult = getEntityManager (). CreateQuery (kriterijiQuery.select (userRoot) .gdje (kriterijiBuilder.equal (userRoot.get ("id"), id))) .getSingleResult (); vratiti queryResult; }

Može biti zastrašujuće za upotrebu Kriteriji API upiti iz prve ruke, ali oni mogu biti izvrstan izbor kada trebamo dodati dinamičke elemente upita ili u kombinaciji s JPA Metamodel.

6. Zaključak

U ovom kratkom članku saznali smo što su JPA upiti, zajedno s njihovom upotrebom.

JPA upiti izvrstan su način da apstrahiramo našu poslovnu logiku s sloja pristupa podacima jer se možemo osloniti na sintaksu JPQL i dopustiti našem odabranom JPA dobavljaču da upravlja Upit prijevod.

Sav kôd predstavljen u ovom članku dostupan je na GitHubu.