Mengehadkan Hasil Pertanyaan dengan JPA dan JPA Data Spring

1. Pengenalan

Dalam tutorial ini, kita akan belajar tentang mengehadkan hasil pertanyaan dengan JPA dan Spring Data JPA.

Pertama, kita akan melihat jadual yang ingin kita tanyakan dan juga pertanyaan SQL yang ingin kita hasilkan semula.

Kemudian kami akan menyelami cara mencapainya dengan JPA dan Spring Data JPA.

Mari kita mulakan!

2. Data Ujian

Di bawah ini terdapat jadual yang akan kami tanyakan sepanjang artikel ini.

Pertanyaan yang ingin kita jawab adalah, "Apa tempat duduk pertama yang diduduki dan siapa yang mendudukinya?".

Nama pertama Nama terakhir Nombor tempat duduk
Jill Smith 50
Hawa Jackson 94
Fred Blogg 22
Ricki Bobbie 36
Siya Kolisi 85

3. SQL

Dengan SQL, kami mungkin menulis pertanyaan yang kelihatan seperti ini:

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

4. Persediaan JPA

Dengan JPA, kami memerlukan Entiti terlebih dahulu, untuk memetakan jadual kami:

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

Seterusnya kita memerlukan kaedah yang merangkumi kod pertanyaan kami, yang dilaksanakan di sini sebagai PassengerRepositoryImpl # findOrderedBySeatNumberLimitedTo (int had) :

@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 kaedah repositori kami, kami menggunakan EntityManager untuk membuat Query di mana kami memanggil kaedah setMaxResults () .

Panggilan ini kepada Query # setMaxResults akhirnya akan menghasilkan pernyataan had yang ditambahkan pada 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 JPA Spring Data

Kami juga dapat menghasilkan SQL kami menggunakan Spring Data JPA.

5.1. pertama atau teratas

Salah satu cara untuk menghampiri ini adalah dengan menggunakan kata nama kaedah dengan kata kunci pertama atau atas.

Kita boleh, secara opsional, menentukan nombor sebagai ukuran hasil maksimum yang akan dikembalikan. Sekiranya kami menghilangkannya, Spring Data JPA menganggap ukuran hasil 1.

Mengingat bahawa kami ingin mengetahui apa tempat duduk pertama yang diduduki dan siapa yang mendudukinya, kami dapat menghilangkannya dengan dua cara berikut:

Passenger findFirstByOrderBySeatNumberAsc(); Passenger findTopByOrderBySeatNumberAsc();

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

Optional findFirstByOrderBySeatNumberAsc(); Optional findTopByOrderBySeatNumberAsc();

5.2. Muka surat

Sebagai alternatif, kita dapat menggunakan objek Halamanable :

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

Jika kita lihat pada pelaksanaan lalai JpaRepository, yang SimpleJpaRepository, kita dapat melihat bahawa ia juga memerlukan Pertanyaan # 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-dua alternatif ini akan menghasilkan SQL yang kita cari:

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 konvensyen pilihan pertama dan teratas dan konfigurasi penyuka halaman

6. Kesimpulannya

Mengehadkan hasil pertanyaan dalam JPA sedikit berbeza dengan SQL - kami tidak memasukkan kata kunci had terus ke dalam JPQL kami.

Sebaliknya, kami hanya membuat satu kaedah panggilan ke Query # maxResults atau memasukkan kata kunci terlebih dahulu atau teratas dalam nama kaedah Spring Data JPA kami.

Seperti biasa, anda boleh mendapatkan kod di GitHub.