Einschränken der Abfrageergebnisse mit JPA und Spring Data JPA

1. Einleitung

In diesem Tutorial erfahren Sie, wie Sie die Abfrageergebnisse mit JPA und Spring Data JPA einschränken .

Zuerst schauen 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 besetzte Platz und wer besetzt ihn?“.

Vorname Familienname, Nachname Sitznummer
Jill Schmied 50
Vorabend Jackson 94
Fred Bloggs 22
Ricki Bobbie 36
Siya Kolisi 85

3. Die SQL

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

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

4. JPA-Setup

Bei 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 als PassengerRepositoryImpl # 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 wir den EntityManager , um eine Abfrage zu erstellen, für die wir die setMaxResults () -Methode aufrufen .

Dieser Aufruf von Query # setMaxResults führt schließlich dazu, dass die Limit-Anweisung an das 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 Spring Data JPA

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

5.1. zuerst oder oben

Eine Möglichkeit, dies zu erreichen, besteht darin, die Ableitung von Methodennamen mit den Schlüsselwörtern first oder top zu verwenden.

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

Wenn wir uns daran erinnern, dass wir wissen möchten, was der erste besetzte Sitz ist und wer ihn besetzt, 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 mit Optional umbrechen :

Optional findFirstByOrderBySeatNumberAsc(); Optional findTopByOrderBySeatNumberAsc();

5.2. Pageable

Alternativ können wir ein Pageable- Objekt verwenden:

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

Wenn wir uns die Standardimplementierung von JpaRepository, dem SimpleJpaRepository, ansehen, können wir sehen, dass es auch Query # setMaxResults aufruft :

protected  Page  readPage(TypedQuery  query, Class  domainClass, Pageable pageable, @Nullable Specification  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 das SQL, nach dem 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 ?

Mit erster und Top- Begünstigung Konvention und Pageable Begünstigung Konfiguration.

6. Fazit

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

Stattdessen führen wir nur einen einzelnen Methodenaufruf für Query # maxResults durch oder fügen das Schlüsselwort zuerst oder oben in unseren Spring Data JPA-Methodennamen ein.

Wie immer finden Sie den Code auf GitHub.