Typer JPA-spørsmål

1. Oversikt

I denne opplæringen vil vi diskutere de forskjellige typene JPA-spørsmål. Videre vil vi fokusere på å sammenligne forskjellene mellom dem og utvide hver enkelt sin fordeler og ulemper.

2. Oppsett

For det første, la oss definere UserEntity klasse vi bruker for alle eksemplene i denne artikkelen:

@Table (name = "brukere") @Entity offentlig klasse UserEntity {@Id privat Lang id; privat strengnavn; // Standardkonstruktør, getters og settere. }

Det er tre grunnleggende typer JPA-spørsmål:

  • Spørsmål, skrevet i Java Persistence Query Language (JPQL) syntaks
  • NativeQuery, skrevet i vanlig SQL-syntaks
  • Criteria API Query, konstruert programmatisk via forskjellige metoder

La oss utforske dem.

3. Spørsmål

EN Spørsmål er lik syntaks og SQL, og den brukes vanligvis til å utføre CRUD-operasjoner:

offentlig UserEntity getUserByIdWithPlainQuery (lang id) {Query jpqlQuery = getEntityManager (). createQuery ("VELG u FRA UserEntity u WHERE u.id =: id"); jpqlQuery.setParameter ("id", id); returner (UserEntity) jpqlQuery.getSingleResult (); }

Dette Spørsmål henter samsvarende post fra brukere og kartlegger den også til UserEntity gjenstand.

Det er to ekstra Spørsmål undertyper:

  • TypedQuery
  • NamedQuery

La oss se dem i aksjon.

3.1. TypedQuery

Vi må ta hensyn til komme tilbake uttalelse i vårt forrige eksempel. JPA kan ikke utlede hva Spørsmål resultatstype vil være, og som et resultat må vi kaste.

Men, JPA gir en spesiell Spørsmål undertype kjent som en TypedQuery.Dette er alltid å foretrekke hvis vi kjenner vårt Spørsmål resultattype på forhånd. I tillegg gjør det koden vår mye mer pålitelig og lettere å teste.

La oss se a TypedQuery alternativ, sammenlignet med vårt første eksempel:

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

Denne måten, vi blir sterkere å skrive gratis, unngå mulige kaste unntak nedover veien.

3.2. NamedQuery

Mens vi dynamisk kan definere en Spørsmål på bestemte metoder, kan de til slutt vokse til en vanskelig å vedlikeholde kodebase. Hva om vi kunne oppbevare generelle spørsmål på et sentralt og lettlest sted?

JPA har også dekket oss på dette med en annen Spørsmål undertype kjent som en NamedQuery.

Vi definerer NamedQueryEnhet klassen selv, og gir en sentralisert, rask og enkel måte å lese og finne Enhet’Relaterte spørsmål.

Alle NamedQueries må ha et unikt navn.

La oss se hvordan vi kan legge til en NamedQuery til vår UserEntity klasse:

@Table (name = "users") @Entity @NamedQuery (name = "UserEntity.findByUserId", query = "VELG u FRA UserEntity u WHERE u.id =: userId") offentlig klasse UserEntity {@Id privat Lang id; privat strengnavn; // Standardkonstruktør, getters og settere. }

De @NamedQuery merknader må grupperes i a @NamedQueries kommentar hvis vi bruker Java før versjon 8. Fra Java 8 fremover kan vi ganske enkelt gjenta @NamedQuery kommentar på vår Enhet klasse.

Bruker en NamedQuery er veldig enkelt:

offentlig UserEntity getUserByIdWithNamedQuery (lang id) {Query namedQuery = getEntityManager (). createNamedQuery ("UserEntity.findByUserId"); heterQuery.setParameter ("userId", id); returner (UserEntity) med navnQuery.getSingleResult (); }

4. NativeQuery

EN NativeQuery er rett og slett et SQL-spørsmål. Disse tillater oss å slippe løs hele kraften i databasen vår, ettersom vi kan bruke proprietære funksjoner som ikke er tilgjengelige i JPQL-begrenset syntaks.

Dette koster noe. Vi mister databaseportabiliteten til applikasjonen vår med NativeQuery fordi JPA-leverandøren ikke lenger kan trekke ut spesifikke detaljer fra implementeringen av databasen eller leverandøren.

La oss se hvordan du bruker en NativeQuery som gir de samme resultatene som våre tidligere eksempler:

offentlig UserEntity getUserByIdWithNativeQuery (lang id) {Query nativeQuery = getEntityManager (). createNativeQuery ("SELECT * FRA brukere WHERE id =: userId", UserEntity.class); nativeQuery.setParameter ("userId", id); returner (UserEntity) nativeQuery.getSingleResult (); }

Vi må alltid vurdere om en NativeQuery er det eneste alternativet. Mesteparten av tiden, en god JPQL Spørsmål kan oppfylle våre behov og viktigst, opprettholde et nivå av abstraksjon fra den faktiske implementeringen av databasen.

Ved hjelp av NativeQuery betyr ikke nødvendigvis å låse oss til en bestemt databaseleverandør. Tross alt, hvis spørsmålene våre ikke bruker proprietære SQL-kommandoer og bare bruker en standard SQL-syntaks, bør bytteleverandører ikke være et problem.

5. Kriterier API-spørring

Kriterier API-spørsmål er programmatisk bygget, typesikre spørsmål - noe som ligner på JPQL-spørsmål i syntaks:

offentlig UserEntity getUserByIdWithCriteriaQuery (lang id) {CriteriaBuilder criteriaBuilder = getEntityManager (). getCriteriaBuilder (); CriteriaQuery criteriaQuery = criteriaBuilder.createQuery (UserEntity.class); Root userRoot = criteriaQuery.from (UserEntity.class); UserEntity queryResult = getEntityManager (). CreateQuery (criteriaQuery.select (userRoot) .where (criteriaBuilder.equal (userRoot.get ("id"), id))) .getSingleResult (); return queryResult; }

Det kan være skremmende å bruke Kriterier API-spørsmål førstehånds, men de kan være et godt valg når vi trenger å legge til dynamiske spørsmålselementer eller når de er koblet til JPA Metamodell.

6. Konklusjon

I denne raske artikkelen lærte vi hva JPA Queries er, sammen med deres bruk.

JPA-spørsmål er en fin måte å trekke vår forretningslogikk ut av datatilgangslaget vårt, ettersom vi kan stole på JPQL-syntaks og la vår valgte JPA-leverandør håndtere Spørsmål oversettelse.

All kode presentert i denne artikkelen er tilgjengelig på GitHub.


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