Membatasi Hasil Query dengan JPA dan Spring Data JPA

1. Perkenalan

Dalam tutorial ini, kita akan belajar tentang membatasi hasil kueri dengan JPA dan Spring Data JPA.

Pertama, kita akan melihat tabel yang ingin kita kueri serta kueri SQL yang ingin kita reproduksi.

Kemudian kita akan mendalami cara mencapainya dengan JPA dan Spring Data JPA.

Ayo mulai!

2. Data Uji

Di bawah ini kami memiliki tabel yang akan kami kueri di seluruh artikel ini.

Pertanyaan yang ingin kami jawab adalah, “Apa kursi yang pertama ditempati dan siapa yang menempatinya?”.

Nama depan Nama keluarga Nomor kursi
Jill Smith 50
Malam Jackson 94
Fred Bloggs 22
Ricki Bobbie 36
Siya Kolisi 85

3. SQL

Dengan SQL kita mungkin menulis kueri yang terlihat seperti ini:

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

4. Pengaturan JPA

Dengan JPA, kita membutuhkan Entitas terlebih dahulu, untuk memetakan tabel kita:

@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. }

Selanjutnya kita membutuhkan metode yang merangkum kode kueri kita, diimplementasikan di sini sebagai PassengerRepositoryImpl # findOrderedBySeatNumberLimitedTo (int limit) :

@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(); } }

Dalam metode repositori kami, kami menggunakan EntityManager untuk membuat Query yang kami sebut metode setMaxResults () .

Panggilan ke Query # setMaxResults ini pada akhirnya akan menghasilkan pernyataan limit yang ditambahkan ke SQL yang dihasilkan:

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. Dengan Spring Data JPA

Kami juga dapat membuat SQL kami menggunakan Spring Data JPA.

5.1. pertama atau teratas

Salah satu cara kita bisa mendekati ini adalah dengan menggunakan metode derivasi nama dengan kata kunci first atau top.

Kita bisa, secara opsional, menentukan angka sebagai ukuran hasil maksimum yang akan dikembalikan. Jika kita menghilangkannya, Spring Data JPA mengasumsikan ukuran hasil 1.

Mengingat bahwa kita ingin tahu apa kursi yang pertama ditempati dan siapa yang menempatinya, kita bisa menghilangkan nomornya dengan dua cara berikut:

Passenger findFirstByOrderBySeatNumberAsc(); Passenger findTopByOrderBySeatNumberAsc();

Jika kita membatasi pada satu hasil contoh, seperti di atas, maka kita juga dapat membungkus hasilnya menggunakan Opsional :

Optional findFirstByOrderBySeatNumberAsc(); Optional findTopByOrderBySeatNumberAsc();

5.2. Pageable

Alternatifnya, kita bisa menggunakan objek Pageable :

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

Jika kita melihat pada implementasi standar dari JpaRepository, yang SimpleJpaRepository, kita dapat melihat bahwa itu juga menyerukan Query # setMaxResults :

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. Perbandingan

Kedua alternatif ini akan menghasilkan SQL yang kita kejar:

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 ?

Dengan konvensi favorit pertama dan teratas serta konfigurasi favorit Pageable .

6. Kesimpulan

Membatasi hasil kueri di JPA sedikit berbeda dengan SQL - kami tidak menyertakan kata kunci batas langsung ke dalam JPQL kami.

Sebagai gantinya, kami hanya membuat satu panggilan metode ke Query # maxResults atau memasukkan kata kunci pertama atau teratas di nama metode JPA Spring Data kami.

Seperti biasa, Anda dapat menemukan kodenya di GitHub.