Paginasi Hibernasi

1. Ikhtisar

Artikel ini adalah pengantar singkat ke Pagination di Hibernate . Kita akan melihat HQL standar serta ScrollableResults API, dan terakhir, pada pagination dengan Kriteria Hibernate.

2. Pagination Dengan HQL dan setFirstResult, setMaxResults API

Cara paling sederhana dan paling umum untuk melakukan pagination di Hibernate adalah menggunakan HQL :

Session session = sessionFactory.openSession(); Query query = sess.createQuery("From Foo"); query.setFirstResult(0); query.setMaxResults(10); List fooList = fooList = query.list();

Contoh ini menggunakan entitas Foo dasar dan sangat mirip dengan JPA dengan implementasi JQL - satu-satunya perbedaan adalah bahasa kueri.

Jika kita mengaktifkan logging untuk Hibernate , kita akan melihat SQL berikut dijalankan:

Hibernate: select foo0_.id as id1_1_, foo0_.name as name2_1_ from Foo foo0_ limit ?

2.1. Hitungan Total dan Halaman Terakhir

Solusi paginasi tidak lengkap tanpa mengetahui jumlah total entitas :

String countQ = "Select count (f.id) from Foo f"; Query countQuery = session.createQuery(countQ); Long countResults = (Long) countQuery.uniqueResult();

Dan terakhir, dari jumlah total dan ukuran halaman tertentu, kita dapat menghitung halaman terakhir :

int pageSize = 10; int lastPageNumber = (int) (Math.ceil(countResults / pageSize));

Pada titik ini kita dapat melihat contoh lengkap untuk penomoran halaman , di mana kita menghitung halaman terakhir dan kemudian mengambilnya:

@Test public void givenEntitiesExist_whenRetrievingLastPage_thenCorrectSize() { int pageSize = 10; String countQ = "Select count (f.id) from Foo f"; Query countQuery = session.createQuery(countQ); Long countResults = (Long) countQuery.uniqueResult(); int lastPageNumber = (int) (Math.ceil(countResults / pageSize)); Query selectQuery = session.createQuery("From Foo"); selectQuery.setFirstResult((lastPageNumber - 1) * pageSize); selectQuery.setMaxResults(pageSize); List lastPage = selectQuery.list(); assertThat(lastPage, hasSize(lessThan(pageSize + 1))); }

3. Pagination Dengan Hibernate Menggunakan HQL dan ScrollableResults API

Menggunakan ScrollableResul ts untuk mengimplementasikan pagination berpotensi mengurangi panggilan database . Pendekatan ini mengalirkan hasil yang ditetapkan saat program menggulirnya, oleh karena itu menghilangkan kebutuhan untuk mengulangi kueri untuk mengisi setiap halaman:

String hql = "FROM Foo f order by f.name"; Query query = session.createQuery(hql); int pageSize = 10; ScrollableResults resultScroll = query.scroll(ScrollMode.FORWARD_ONLY); resultScroll.first(); resultScroll.scroll(0); List fooPage = Lists.newArrayList(); int i = 0; while (pageSize > i++) { fooPage.add((Foo) resultScroll.get(0)); if (!resultScroll.next()) break; }

Metode ini tidak hanya efisien waktu (hanya satu panggilan database), tetapi memungkinkan pengguna untuk mendapatkan akses ke jumlah total kumpulan hasil tanpa kueri tambahan :

resultScroll.last(); int totalResults = resultScroll.getRowNumber() + 1;

Di sisi lain, perlu diingat bahwa, meskipun pengguliran cukup efisien, jendela besar mungkin membutuhkan memori yang cukup .

4. Penomoran Halaman Dengan Hibernasi Menggunakan API Kriteria

Terakhir, mari kita lihat solusi yang lebih fleksibel - menggunakan kriteria:

Criteria criteria = session.createCriteria(Foo.class); criteria.setFirstResult(0); criteria.setMaxResults(pageSize); List firstPage = criteria.list();

API kueri Kriteria Hibernasi membuatnya sangat mudah juga untuk mendapatkan jumlah total - dengan menggunakan objek Proyeksi :

Criteria criteriaCount = session.createCriteria(Foo.class); criteriaCount.setProjection(Projections.rowCount()); Long count = (Long) criteriaCount.uniqueResult();

Seperti yang Anda lihat, menggunakan API ini akan menghasilkan kode verbose yang lebih sedikit daripada HQL biasa, tetapi API tersebut sepenuhnya aman dan jauh lebih fleksibel .

5. Kesimpulan

Artikel ini adalah pengantar singkat untuk berbagai cara melakukan pagination di Hibernate.

Penerapan Tutorial JPA Musim Semi ini dapat ditemukan di proyek GitHub - ini adalah proyek berbasis Eclipse, jadi semestinya mudah untuk mengimpor dan menjalankan apa adanya.