Typer af JPA-forespørgsler

1. Oversigt

I denne vejledning diskuterer vi de forskellige typer JPA-forespørgsler. Desuden vil vi fokusere på at sammenligne forskellene mellem dem og udvide hinandens fordele og ulemper.

2. Opsætning

Lad os først definere UserEntity klasse, vi bruger til alle eksempler i denne artikel:

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

Der er tre grundlæggende typer af JPA-forespørgsler:

  • Forespørgsel, skrevet i Java Persistence Query Language (JPQL) syntaks
  • NativeQuery, skrevet i almindelig SQL-syntaks
  • Kriterier API-forespørgsel, konstrueret programmatisk via forskellige metoder

Lad os udforske dem.

3. Forespørgsel

EN Forespørgsel ligner syntaksen SQL, og den bruges normalt til at udføre CRUD-operationer:

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

Det her Forespørgsel henter den matchende post fra brugere tabel og kortlægger det også til UserEntity objekt.

Der er to ekstra Forespørgsel undertyper:

  • TypedQuery
  • NamedQuery

Lad os se dem i aktion.

3.1. TypedQuery

Vi skal være opmærksomme på Vend tilbage erklæring i vores tidligere eksempel. JPA kan ikke udlede, hvad Forespørgsel resultattype vil være, og som et resultat skal vi kaste.

Men, JPA giver en særlig Forespørgsel undertype kendt som en TypedQuery.Dette foretrækkes altid, hvis vi kender vores Forespørgsel resultattype på forhånd. Derudover gør det vores kode meget mere pålidelig og lettere at teste.

Lad os se en TypedQuery alternativ sammenlignet med vores første eksempel:

offentlig UserEntity getUserByIdWithTypedQuery (Lang id) {TypedQuery typedQuery = getEntityManager (). createQuery ("VÆLG u FRA UserEntity u WHERE u.id =: id", UserEntity.class); typedQuery.setParameter ("id", id); returner typedQuery.getSingleResult (); }

Denne måde, vi bliver stærkere at skrive gratis, undgå mulige casting undtagelser ned ad vejen.

3.2. NamedQuery

Mens vi dynamisk kan definere en Forespørgsel på specifikke metoder kan de til sidst vokse til en svær at vedligeholde kodebase. Hvad hvis vi kunne opbevare generelle brugsforespørgsler på et centralt, letlæsbart sted?

JPA fik os også dækket af dette med en anden Forespørgsel undertype kendt som en NamedQuery.

Vi definerer NamedQuery på den Enhed klassen selv og giver en central, hurtig og nem måde at læse og finde på Enhed'S relaterede forespørgsler.

Alle NamedQueries skal have et unikt navn.

Lad os se, hvordan vi kan tilføje en NamedQuery til vores UserEntity klasse:

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

Det @NamedQuery annotering skal grupperes i en @NamedQueries kommentar, hvis vi bruger Java før version 8. Fra Java 8 fremad kan vi simpelthen gentage @NamedQuery kommentar på vores Enhed klasse.

Brug af en NamedQuery er meget simpelt:

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

4. NativeQuery

EN NativeQuery er simpelthen en SQL-forespørgsel. Disse giver os mulighed for at frigøre den fulde kraft i vores database, da vi kan bruge proprietære funktioner, der ikke er tilgængelige i JPQL-begrænset syntaks.

Dette koster en pris. Vi mister databaseportabilitet af vores applikation med NativeQuery fordi vores JPA-udbyder ikke længere kan abstrakte specifikke detaljer fra databaseimplementeringen eller leverandøren.

Lad os se, hvordan man bruger en NativeQuery der giver de samme resultater som vores tidligere eksempler:

offentlig UserEntity getUserByIdWithNativeQuery (lang id) {Query nativeQuery = getEntityManager (). createNativeQuery ("VÆLG * FRA brugere HVOR id =: userId", UserEntity.class); nativeQuery.setParameter ("userId", id); returner (UserEntity) nativeQuery.getSingleResult (); }

Vi skal altid overveje, om en NativeQuery er den eneste mulighed. Det meste af tiden en god JPQL Forespørgsel kan opfylde vores behov og vigtigst af alt opretholde et abstraktionsniveau fra den faktiske databaseimplementering.

Ved brug af NativeQuery betyder ikke nødvendigvis at låse os til en bestemt databaseleverandør. Når alt kommer til alt, hvis vores forespørgsler ikke bruger proprietære SQL-kommandoer og kun bruger en standard SQL-syntaks, bør det ikke være et problem at skifte udbyder.

5. Kriterier API-forespørgsel

Kriterier API-forespørgsler er programmatisk bygget, typesikre forespørgsler - svarer til JPQL-forespørgsler 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 (); returner forespørgselResultat; }

Det kan være skræmmende at bruge Kriterier API-forespørgsler førstehånds, men de kan være et godt valg, når vi har brug for at tilføje dynamiske forespørgselselementer eller når de er koblet til JPA Metamodel.

6. Konklusion

I denne hurtige artikel lærte vi, hvad JPA-forespørgsler er sammen med deres brug.

JPA-forespørgsler er en fantastisk måde at abstrakte vores forretningslogik fra vores dataadgangslag, da vi kan stole på JPQL-syntaks og lade vores valgte JPA-udbyder håndtere Forespørgsel oversættelse.

Al kode præsenteret i denne artikel er tilgængelig på GitHub.