Pagination Hibernation

1. Vue d'ensemble

Cet article est une introduction rapide à la pagination dans Hibernate . Nous examinerons le HQL standard ainsi que l' API ScrollableResults , et enfin, la pagination avec Hibernate Criteria.

2. Pagination Avec HQL et setFirstResult, API setMaxResults

Le moyen le plus simple et le plus courant de paginer dans Hibernate consiste à utiliser HQL :

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

Cet exemple utilise une entité Foo de base et est très similaire à l'implémentation JPA avec JQL - la seule différence étant le langage de requête.

Si nous activons la journalisation pour Hibernate , nous verrons le SQL suivant en cours d'exécution:

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

2.1. Le nombre total et la dernière page

Une solution de pagination n'est pas complète sans connaître le nombre total d'entités :

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

Et enfin, à partir du nombre total et d'une taille de page donnée, on peut calculer la dernière page :

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

À ce stade, nous pouvons regarder un exemple complet de pagination , où nous calculons la dernière page, puis la récupérons:

@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 avec Hibernate en utilisant HQL et l'API ScrollableResults

L'utilisation de ScrollableResul ts pour implémenter la pagination a le potentiel de réduire les appels à la base de données . Cette approche diffuse l'ensemble de résultats au fur et à mesure que le programme le fait défiler, éliminant ainsi le besoin de répéter la requête pour remplir chaque page:

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; }

Cette méthode est non seulement efficace en termes de temps (un seul appel de base de données), mais elle permet à l'utilisateur d'accéder au nombre total de l'ensemble de résultats sans requête supplémentaire :

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

D'autre part, gardez à l'esprit que, bien que le défilement soit assez efficace, une grande fenêtre peut occuper une quantité décente de mémoire .

4. Pagination avec Hibernate à l'aide de l'API Criteria

Enfin, regardons une solution plus flexible - en utilisant des critères:

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

L'API de requête Hibernate Criteria simplifie également l' obtention du nombre total - en utilisant un objet Projection :

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

Comme vous pouvez le voir, l'utilisation de cette API entraînera un code légèrement plus détaillé que le HQL simple, mais l'API est entièrement sécurisée et beaucoup plus flexible .

5. Conclusion

Cet article est une introduction rapide aux différentes méthodes de pagination dans Hibernate.

L'implémentation de ce tutoriel Spring JPA se trouve dans le projet GitHub - il s'agit d'un projet basé sur Eclipse, il devrait donc être facile à importer et à exécuter tel quel.