Begrenzung der Abfrageergebnisse mit JPA und Spring Data JPA

Einschränken der Abfrageergebnisse mit JPA und Spring Data JPA

1. Einführung

In diesem Tutorial gehen wir zulearn about limiting query results mitJPA undSpring Data JPA.

Zunächst sehen wir uns die Tabelle an, die wir abfragen möchten, sowie die SQL-Abfrage, die wir reproduzieren möchten.

Dann werden wir gleich untersuchen, wie dies mit JPA und Spring Data JPA erreicht werden kann.

Lass uns anfangen!

2. Die Testdaten

Unten finden Sie die Tabelle, die wir in diesem Artikel abfragen werden.

Die Frage, die wir beantworten möchten, lautet: „Was ist der erste belegte Platz und wer belegt ihn?“.

Vorname

Nachname

Sitznummer

Jill

Schmied

50

Eve

Jackson

94

Fred

Bloggs

22

Ricki

Bobbie

36

Siya

Kolisi

85

3. Die SQL

Mit SQL können wir eine Abfrage schreiben, die ungefähr so ​​aussieht:

SELECT firstName, lastName, seatNumber FROM passengers ORDER BY seatNumber LIMIT 1;

4. JPA-Setup

Mit JPA benötigen wir zuerst eine Entität, um unsere Tabelle abzubilden:

@Entity
class Passenger {

    @Id
    @GeneratedValue
    @Column(nullable = false)
    private Long id;

    @Basic(optional = false)
    @Column(nullable = false)
    private String fistName;

    @Basic(optional = false)
    @Column(nullable = false)
    private String lastName;

    @Basic(optional = false)
    @Column(nullable = false)
    private int seatNumber;

    // constructor, getters etc.
}

Als nächstes benötigen wir eine Methode, die unseren Abfragecode kapselt und hier alsPassengerRepositoryImpl#findOrderedBySeatNumberLimitedTo(int limit) implementiert ist:

@Repository
class PassengerRepositoryImpl {

    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public List findOrderedBySeatNumberLimitedTo(int limit) {
        return entityManager.createQuery("SELECT p FROM Passenger p ORDER BY p.seatNumber",
          Passenger.class).setMaxResults(limit).getResultList();
    }
}

In unserer Repository-Methode verwenden wirEntityManager, umQuery zu erstellen, für die wir diesetMaxResults()-Methode aufrufen.

Dieser Aufruf vonQuery#setMaxResults führt schließlich dazu, dass die Limit-Anweisung an die generierte SQL angehängt wird:

select
  passenger0_.id as id1_15_,
  passenger0_.fist_name as fist_nam2_15_,
  passenger0_.last_name as last_nam3_15_,
  passenger0_.seat_number as seat_num4_15_
from passenger passenger0_ order by passenger0_.seat_number limit ?

5. Mit Federdaten JPA

Wir können unsere SQL auch mit Spring Data JPA generieren.

5.1. first odertop

Eine Möglichkeit, dies zu erreichen, besteht darin, die Ableitung von Methodennamen mit den Schlüsselwörternfirst odertop. zu verwenden

Optional können wir eine Zahl als maximale Ergebnisgröße angeben, die zurückgegeben wird. Wenn wir es weglassen, geht Spring Data JPA von einer Ergebnisgröße von 1 aus.

Wenn wir uns daran erinnern, dass wir wissen möchten, was der erste Sitzplatz ist und wer ihn belegt, können wir die Nummer auf zwei Arten weglassen:

Passenger findFirstByOrderBySeatNumberAsc();
Passenger findTopByOrderBySeatNumberAsc();

Wenn wir uns wie oben auf ein Instanzergebnis beschränken, können wir das Ergebnis auch mitOptional umbrechen:

Optional findFirstByOrderBySeatNumberAsc();
Optional findTopByOrderBySeatNumberAsc();

5.2. Pageable

Alternativ können wir einPageable-Objekt verwenden:

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

Wenn wir uns die Standardimplementierung vonJpaRepository, ansehen, kannSimpleJpaRepositorywe sehen, dass es auchQuery#setMaxResults aufruft:

protected  Page < S > readPage(TypedQuery < S > query,
  Class < S > domainClass, Pageable pageable,
  @Nullable Specification < S > spec) {
    if (pageable.isPaged()) {
        query.setFirstResult((int) pageable.getOffset());
        query.setMaxResults(pageable.getPageSize());
    }

    return PageableExecutionUtils.getPage(query.getResultList(), pageable, () -> {
        return executeCountQuery(this.getCountQuery(spec, domainClass));
    });
}

5.3. Vergleich

Beide Alternativen erzeugen die SQL, nach der wir suchen:

select
  passenger0_.id as id1_15_,
  passenger0_.fist_name as fist_nam2_15_,
  passenger0_.last_name as last_nam3_15_,
  passenger0_.seat_number as seat_num4_15_
from passenger passenger0_ order by passenger0_.seat_number asc limit ?

Mitfirst andtopbevorzugt Konvention undPageablebevorzugt Konfiguration.

6. Fazit

Das Einschränken der Abfrageergebnisse inJPA unterscheidet sich geringfügig von SQL. Das Schlüsselwort limit wird nicht direkt in unsereJPQL aufgenommen.

Stattdessen führen wir nur einen einzelnen Methodenaufruf fürQuery#maxResults durch oder fügen das Schlüsselwortfirst odertop in unseren MethodennamenSpring Data JPAein.

Wie immer finden Sie den Codeover on GitHub.