Typen JPA-zoekopdrachten

1. Overzicht

In deze tutorial bespreken we de verschillende soorten JPA-query's. Bovendien zullen we ons concentreren op het vergelijken van de verschillen tussen hen en het uitbreiden van ieders voor- en nadelen.

2. Installatie

Laten we eerst de UserEntity klasse die we zullen gebruiken voor alle voorbeelden in dit artikel:

@Table (name = "gebruikers") @Entity openbare klasse UserEntity {@Id privé Lange id; private String naam; // Standaard constructeur, getters en setters. }

Er zijn drie basistypen JPA-zoekopdrachten:

  • Vraag, geschreven in de syntaxis van Java Persistence Query Language (JPQL)
  • NativeQuery, geschreven in gewone SQL-syntaxis
  • Criteria API-zoekopdracht, programmatisch opgebouwd via verschillende methoden

Laten we ze verkennen.

3. Vraag

EEN Vraag is vergelijkbaar in syntaxis met SQL, en wordt over het algemeen gebruikt om CRUD-bewerkingen uit te voeren:

openbare UserEntity getUserByIdWithPlainQuery (lange id) {Query jpqlQuery = getEntityManager (). createQuery ("SELECTEER u UIT UserEntity u WAAR u.id =: id"); jpqlQuery.setParameter ("id", id); return (UserEntity) jpqlQuery.getSingleResult (); }

Dit Vraag haalt het overeenkomende record op uit de gebruikers tabel en wijst deze ook toe aan de UserEntity voorwerp.

Er zijn er nog twee Vraag subtypen:

  • TypedQuery
  • NamedQuery

Laten we ze in actie zien.

3.1. TypedQuery

We moeten aandacht besteden aan de terugkeer verklaring in ons vorige voorbeeld. De PPV kan niet afleiden wat het Vraag resultaattype zal zijn, en als gevolg daarvan moeten we casten.

Maar, JPA biedt een special Vraag subtype dat bekend staat als een TypedQuery.Dit heeft altijd de voorkeur als we onze kennen Vraag resultaattype vooraf. Bovendien maakt het onze code veel betrouwbaarder en gemakkelijker te testen.

Laten we eens kijken naar een TypedQuery alternatief, vergeleken met ons eerste voorbeeld:

openbare UserEntity getUserByIdWithTypedQuery (lange id) {TypedQuery typedQuery = getEntityManager (). createQuery ("SELECTEER u VAN UserEntity u WHERE u.id =: id", UserEntity.class); typedQuery.setParameter ("id", id); retourneer typedQuery.getSingleResult (); }

Op deze manier we krijgen gratis sterker typen, mogelijke gietuitzonderingen op de weg vermijden.

3.2. NamedQuery

Hoewel we dynamisch een Vraag op specifieke methoden kunnen ze uiteindelijk uitgroeien tot een moeilijk te onderhouden codebasis. Wat als we algemene gebruiksvragen op één gecentraliseerde, gemakkelijk te lezen plaats zouden kunnen bewaren?

JPA heeft ons hierover ook gedekt met een ander Vraag subtype dat bekend staat als een NamedQuery.

We definiëren NamedQuery op de Entiteit klasse zelf, wat een gecentraliseerde, snelle en gemakkelijke manier biedt om te lezen en te vinden Entiteit‘Gerelateerde zoekopdrachten.

Alle NamedQueries moet een unieke naam hebben.

Laten we eens kijken hoe we een NamedQuery naar onze UserEntity klasse:

@Table (name = "gebruikers") @Entity @NamedQuery (name = "UserEntity.findByUserId", query = "SELECTEER u UIT UserEntity u WAAR u.id =: userId") openbare klasse UserEntity {@Id private Lange id; private String naam; // Standaard constructeur, getters en setters. }

De @NamedQuery annotatie moet worden gegroepeerd in een @NamedQueries annotatie als we Java vóór versie 8 gebruiken. Vanaf Java 8 kunnen we de @NamedQuery annotatie op onze Entiteit klasse.

Gebruik maken van een NamedQuery is heel simpel:

openbare UserEntity getUserByIdWithNamedQuery (lange id) {Query namedQuery = getEntityManager (). createNamedQuery ("UserEntity.findByUserId"); namedQuery.setParameter ("userId", id); return (UserEntity) namedQuery.getSingleResult (); }

4. NativeQuery

EEN NativeQuery is gewoon een SQL-query. Deze stellen ons in staat om de volledige kracht van onze database te ontketenen, aangezien we eigen functies kunnen gebruiken die niet beschikbaar zijn in JPQL-beperkte syntaxis.

Dit brengt kosten met zich mee. We verliezen de databaseportabiliteit van onze applicatie met NativeQuery omdat onze JPA-provider specifieke details van de database-implementatie of leverancier niet meer kan abstraheren.

Laten we eens kijken hoe we een NativeQuery dat dezelfde resultaten oplevert als onze vorige voorbeelden:

openbare UserEntity getUserByIdWithNativeQuery (lange id) {Query nativeQuery = getEntityManager (). createNativeQuery ("SELECTEER * VAN gebruikers WHERE id =: userId", UserEntity.class); nativeQuery.setParameter ("userId", id); return (UserEntity) nativeQuery.getSingleResult (); }

We moeten altijd overwegen of a NativeQuery is de enige optie. Meestal een goede JPQL Vraag kan aan onze behoeften voldoen en vooral, een abstractieniveau behouden van de feitelijke database-implementatie.

Gebruik makend van NativeQuery betekent niet noodzakelijk dat we ons moeten vastleggen op één specifieke databaseleverancier. Als onze zoekopdrachten geen eigen SQL-opdrachten gebruiken en alleen een standaard SQL-syntaxis gebruiken, zou het wisselen van provider geen probleem moeten zijn.

5. Criteria API-zoekopdracht

Criteria API-query's zijn programmatisch gebouwde, typeveilige query's - enigszins vergelijkbaar met JPQL-query's in syntaxis:

openbare UserEntity getUserByIdWithCriteriaQuery (lange 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 (); retourneer queryResult; }

Het kan ontmoedigend zijn om te gebruiken Criteria API-query's uit de eerste hand, maar ze kunnen een goede keuze zijn wanneer we dynamische query-elementen moeten toevoegen of in combinatie met de JPA Metamodel.

6. Conclusie

In dit korte artikel hebben we geleerd wat JPA-zoekopdrachten zijn, samen met het gebruik ervan.

JPA-zoekopdrachten zijn een uitstekende manier om onze bedrijfslogica te abstraheren van onze gegevenstoegangslaag, omdat we kunnen vertrouwen op de JPQL-syntaxis en onze JPA-provider naar keuze de Vraag vertaling.

Alle code die in dit artikel wordt gepresenteerd, is beschikbaar op GitHub.


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