Karena ini adalah pertanyaan yang sangat umum, saya menulis
artikel ini , yang menjadi dasar jawaban ini.
The setFirstResult
dan setMaxResults
Query
metode
Untuk JPA dan Hibernate Query
, setFirstResult
metode ini setara dengan OFFSET
, dan setMaxResults
metode ini setara dengan LIMIT:
List<Post> posts = entityManager
.createQuery(
"select p " +
"from Post p " +
"order by p.createdOn ")
.setFirstResult(10)
.setMaxResults(10)
.getResultList();
The LimitHandler
abstraksi
Hibernate LimitHandler
mendefinisikan logika pagination-spesifik-database, dan seperti yang diilustrasikan oleh diagram berikut, Hibernate mendukung banyak opsi pagination-spesifik-database:
Sekarang, tergantung pada sistem basis data relasional yang Anda gunakan, kueri JPQL di atas akan menggunakan sintaks pagination yang tepat.
MySQL
SELECT p.id AS id1_0_,
p.created_on AS created_2_0_,
p.title AS title3_0_
FROM post p
ORDER BY p.created_on
LIMIT ?, ?
PostgreSQL
SELECT p.id AS id1_0_,
p.created_on AS created_2_0_,
p.title AS title3_0_
FROM post p
ORDER BY p.created_on
LIMIT ?
OFFSET ?
SQL Server
SELECT p.id AS id1_0_,
p.created_on AS created_on2_0_,
p.title AS title3_0_
FROM post p
ORDER BY p.created_on
OFFSET ? ROWS
FETCH NEXT ? ROWS ONLY
Peramal
SELECT *
FROM (
SELECT
row_.*, rownum rownum_
FROM (
SELECT
p.id AS id1_0_,
p.created_on AS created_on2_0_,
p.title AS title3_0_
FROM post p
ORDER BY p.created_on
) row_
WHERE rownum <= ?
)
WHERE rownum_ > ?
Keuntungan menggunakan setFirstResult
dan setMaxResults
adalah bahwa Hibernate dapat menghasilkan sintaks pagination khusus-database untuk setiap basis data relasional yang didukung.
Dan, Anda tidak terbatas pada permintaan JPQL saja. Anda bisa menggunakan setFirstResult
dan setMaxResults
metode tujuh untuk kueri SQL asli.
Kueri SQL asli
Anda tidak perlu melakukan hardcode pagination khusus basis data saat menggunakan query SQL asli. Hibernate dapat menambahkan itu ke kueri Anda.
Jadi, jika Anda menjalankan query SQL ini pada PostgreSQL:
List<Tuple> posts = entityManager
.createNativeQuery(
"SELECT " +
" p.id AS id, " +
" p.title AS title " +
"from post p " +
"ORDER BY p.created_on", Tuple.class)
.setFirstResult(10)
.setMaxResults(10)
.getResultList();
Hibernate akan mengubahnya sebagai berikut:
SELECT p.id AS id,
p.title AS title
FROM post p
ORDER BY p.created_on
LIMIT ?
OFFSET ?
Keren kan?
Di luar pagination berbasis SQL
Pagination bagus ketika Anda dapat mengindeks kriteria pemfilteran dan pengurutan. Jika persyaratan halaman Anda menyiratkan penyaringan dinamis, itu pendekatan yang jauh lebih baik untuk menggunakan solusi indeks terbalik, seperti ElasticSearch.
Lihat artikel ini untuk lebih jelasnya.
Hibernate-5.0.12
. Apakah ini masih belum tersedia? Akan sangat berat untuk mendapatkan satu juta atau lebih catatan dan kemudian menerapkan filter di atasnya-setMaxResults
seperti yang diperhatikan oleh @Rachel dalam jawaban oleh @skaffman.