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.