Queryresultaten beperken met JPA en Spring Data JPA

1. Inleiding

In deze tutorial gaan we dat doen meer informatie over het beperken van queryresultaten met JPA en Spring Data JPA.

Eerst kijken we naar de tabel die we willen opvragen en naar de SQL-query die we willen reproduceren.

Daarna gaan we meteen in op hoe u dat kunt bereiken met JPA en Spring Data JPA.

Laten we beginnen!

2. De testgegevens

Hieronder hebben we de tabel die we in dit artikel zullen doorzoeken.

De vraag die we willen beantwoorden is: “Wat is de eerste bezette stoel en wie bezet deze?”.

VoornaamAchternaamStoelnummer
JillSmith50
VooravondJackson94
FredBloggs22
RickiBobbie36
SiyaKolisi85

3. De SQL

Met SQL kunnen we een query schrijven die er ongeveer zo uitziet:

SELECTEER voornaam, achternaam, stoelnummer VAN passagiers BESTEL OP stoelnummer LIMIET 1;

4. JPA-instellingen

Met JPA hebben we eerst een entiteit nodig om onze tabel in kaart te brengen:

@Entity class Passenger {@Id @GeneratedValue @Column (nullable = false) privé Lange id; @Basic (optioneel = false) @Column (nullable = false) private String fistName; @Basic (optioneel = false) @Column (nullable = false) private String lastName; @Basic (optioneel = false) @Column (nullable = false) private int seatNumber; // constructor, getters etc.}

Vervolgens hebben we een methode nodig die onze querycode omvat, hier geïmplementeerd als PassengerRepositoryImpl # findOrderedBySeatNumberLimitedTo (int limiet):

@Repository klasse PassengerRepositoryImpl {@PersistenceContext private EntityManager entityManager; @Override openbare lijst findOrderedBySeatNumberLimitedTo (int limit) {return entityManager.createQuery ("SELECT p FROM Passenger p ORDER BY p.seatNumber", Passenger.class) .setMaxResults (limit) .getResultList (); }}

In onze repository-methode gebruiken we de EntityManager om een Vraag waarop we de setMaxResults () methode.

Deze oproep aan Vraag # setMaxResults zal uiteindelijk resulteren in de limit-instructie die aan de gegenereerde SQL wordt toegevoegd:

selecteer passagier0_.id als id1_15_, passagier0_.vuist_naam als vuist_nam2_15_, passagier0_.last_naam als laatste_nam3_15_, passagier0_.zetelnummer als stoel_num4_15_ van passagier passagier0_ volgorde door passagier0_.zetelnummer limiet?

5. Met Spring Data JPA

We kunnen onze SQL ook genereren met Spring Data JPA.

5.1. eerste of top

Een manier waarop we dit kunnen benaderen, is door gebruik te maken van methode naamafleiding met de trefwoorden eerste of top.

We kunnen optioneel een getal specificeren als de maximale resultaatgrootte die zal worden geretourneerd. Als we het weglaten, gaat Spring Data JPA uit van een resultaatgrootte van 1.

Als we bedenken dat we willen weten wat de eerste bezette stoel is en wie deze bezet, kunnen we ervoor zorgen dat het nummer op deze twee manieren wordt weggelaten:

Passagier findFirstByOrderBySeatNumberAsc (); Passagier findTopByOrderBySeatNumberAsc ();

Als we ons beperken tot één instantieresultaat, zoals hierboven, dan kunnen we het resultaat ook verpakken met Optioneel:

Optioneel findFirstByOrderBySeatNumberAsc (); Optioneel findTopByOrderBySeatNumberAsc ();

5.2. Pageable

Als alternatief kunnen we een Pageable voorwerp:

Paginapagina = repository.findAll (PageRequest.of (0, 1, Sort.by (Sort.Direction.ASC, "seatNumber")));

Als we kijken naar de standaardimplementatie van JpaRepository, de SimpleJpaRepository, we kunnen zien dat het ook belt Vraag # setMaxResults:

beschermde pagina readPage (TypedQuery-query, Class domainClass, Pageable pageable, @Nullable Specification spec) {if (pageable.isPaged ()) {query.setFirstResult ((int) pageable.getOffset ()); query.setMaxResults (pageable.getPageSize ()); } retourneer PageableExecutionUtils.getPage (query.getResultList (), pageable, () -> {retourneer executeCountQuery (this.getCountQuery (spec, domainClass));}); }

5.3. Vergelijking

Beide alternatieven zullen de SQL produceren waarnaar we op zoek zijn:

selecteer passagier0_.id als id1_15_, passagier0_.vuist_naam als vuist_nam2_15_, passagier0_.last_naam als laatste_nam3_15_, passagier0_.seat_nummer als stoel_num4_15_ van passagier passagier0_ volgorde door passagier0_.seat_nummer oplopend?

Met eerste en top voorkeur voor conventie en Pageable voorkeur voor configuratie.

6. Conclusie

Het beperken van queryresultaten in JPA is iets anders dan in SQL - we nemen het trefwoord limit niet rechtstreeks op in onze JPQL.

In plaats daarvan maken we slechts één methodeaanroep naar Vraag # maxResults of voeg het trefwoord toe eerste of top in onze Spring Data JPA-methode naam.

Zoals altijd kun je de code vinden op GitHub.