Pagination Hibernate

Hibernate Pagination

1. Vue d'ensemble

Cet article est un rapideintroduction to Pagination in Hibernate. Nous examinerons le HQL standard ainsi que l'APIScrollableResults, et enfin, la pagination avec Hibernate Criteria.

Lectures complémentaires:

Démarrer Hibernate 5 avec Spring

Un guide rapide et pratique pour intégrer Hibernate 5 à Spring.

Read more

Cartographie d'héritage Hibernate

Un guide pratique pour comprendre différentes stratégies de cartographie d'héritage avec JPA / Hibernate.

Read more

Afficher les instructions SQL Hibernate / JPA à partir du démarrage printanier

Découvrez comment configurer la consignation des instructions SQL générées dans votre application Spring Boot.

Read more

2. Pagination avec HQL etsetFirstResult,setMaxResults API

Le moyen le plus simple et le plus courant de paginer dans Hibernate estusing 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é de baseFoo et est très similaire à l'implémentation JPA avec JQL - la seule différence étant le langage de requête.

Si nous activonslogging for Hibernate, nous verrons le SQL suivant s'exécuter:

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îtrethe total number of entities:

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 calculerthe last page:

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

À ce stade, nous pouvons regardera complete example for 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 à l'aide de HQL et de l'API ScrollableResults

L'utilisation deScrollableResults pour implémenter la pagination a le potentiel dereduce database calls. Cette approche diffuse le jeu de résultats lorsque le programme le fait défiler, éliminant ainsi la nécessité 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 temps (un seul appel de base de données), mais elle permet à l'utilisateur d'accéder auxtotal count of the result set without an additional query:

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 prendre une quantité décente dememory.

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

Enfin, regardonsa more flexible solution - en utilisant les 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'utilisation deget the total count - en utilisant un objetProjection:

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 ordinaire, maisthe API is fully type safe and a lot more flexible.

5. Conclusion

Cet article est une introduction rapide aux différentes façons de faire la pagination dans Hibernate.

L'implémentation de ce tutoriel Spring JPA peut être trouvée dansthe GitHub project - il s'agit d'un projet basé sur Eclipse, il devrait donc être facile à importer et à exécuter tel quel.