Hibernate Pagination

1. Gambaran keseluruhan

Artikel ini adalah pengenalan ringkas mengenai Pagination in Hibernate . Kita akan melihat HQL standard serta ScrollableResults API, dan akhirnya, di muka surat dengan Kriteria Hibernate.

2. Pagination With HQL dan setFirstResult, setMaxResults API

Kaedah paling mudah dan paling biasa untuk melakukan penomboran 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 entiti Foo asas dan sangat serupa dengan JPA dengan pelaksanaan JQL - satu-satunya perbezaan adalah bahasa pertanyaan.

Sekiranya kita menghidupkan log 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. Jumlah Jumlah dan Halaman Terakhir

Penyelesaian penomboran tidak lengkap tanpa mengetahui jumlah entiti :

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

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

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

Pada ketika ini kita dapat melihat contoh lengkap untuk penomboran , di mana kita mengira 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. Penomboran Dengan Hibernate Menggunakan HQL dan API ScrollableResults

Menggunakan ScrollableResul ts untuk melaksanakan penomboran berpotensi untuk mengurangkan panggilan pangkalan data . Pendekatan ini mengalirkan hasil yang ditetapkan semasa program menelusurinya, sehingga menghilangkan kebutuhan untuk mengulangi pertanyaan 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; }

Kaedah ini bukan hanya menjimatkan masa (hanya satu panggilan pangkalan data), tetapi memungkinkan pengguna mendapatkan akses ke jumlah hasil yang ditetapkan tanpa pertanyaan tambahan :

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

Sebaliknya, ingatlah bahawa, walaupun menatal cukup cekap, tetingkap besar mungkin memerlukan banyak memori .

4. Penomboran Dengan Hibernate Menggunakan API Kriteria

Akhirnya, mari kita lihat penyelesaian yang lebih fleksibel - menggunakan kriteria:

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

API pertanyaan Kriteria Hibernate menjadikannya sangat mudah untuk mendapatkan jumlah keseluruhan - dengan menggunakan objek Unjuran :

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

Seperti yang anda lihat, menggunakan API ini akan menghasilkan kod verbose yang lebih minimum daripada HQL biasa, tetapi API sepenuhnya jenis selamat dan lebih fleksibel .

5. Kesimpulan

Artikel ini adalah pengenalan ringkas mengenai pelbagai cara melakukan penomboran di Hibernate.

Pelaksanaan Tutorial Spring JPA ini boleh didapati di projek GitHub - ini adalah projek berasaskan Eclipse, jadi semestinya mudah untuk diimport dan dijalankan sebagaimana adanya.