Paginação de hibernação

Paginação de hibernação

1. Visão geral

Este artigo é umintroduction to Pagination in Hibernate rápido. Veremos o HQL padrão, bem como a APIScrollableResults e, finalmente, a paginação com os critérios do Hibernate.

Leitura adicional:

Inicializando o Hibernate 5 com Spring

Um guia rápido e prático para integrar o Hibernate 5 ao Spring.

Read more

Mapeamento de herança de hibernação

Um guia prático para entender as diferentes estratégias de mapeamento de herança com o JPA / Hibernate.

Read more

Mostrar instruções SQL Hibernate / JPA a partir do Spring Boot

Aprenda como você pode configurar o log das instruções SQL geradas no aplicativo Spring Boot.

Read more

2. Paginação com HQL esetFirstResult, APIsetMaxResults

A maneira mais simples e comum de fazer paginação no Hibernate éusing HQL:

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

Este exemplo está usando uma entidadeFoo básica e é muito semelhante ao JPA com implementação JQL - a única diferença é a linguagem de consulta.

Se ligarmoslogging for Hibernate, veremos o seguinte SQL sendo executado:

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

2.1. A contagem total e a última página

Uma solução de paginação não está completa sem saberthe total number of entities:

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

E, por último, a partir do número total e um determinado tamanho de página, podemos calcularthe last page:

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

Neste ponto, podemos olhar paraa complete example for pagination, onde estamos calculando a última página e, em seguida, recuperando-a:

@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. Paginação com Hibernate usando HQL e a API ScrollableResults

UsarScrollableResults para implementar a paginação tem potencial parareduce database calls. Essa abordagem transmite o conjunto de resultados à medida que o programa o percorre, eliminando a necessidade de repetir a consulta para preencher cada página:

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

Este método não é apenas eficiente em termos de tempo (apenas uma chamada de banco de dados), mas permite que o usuário obtenha acesso aototal count of the result set without an additional query:

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

Por outro lado, tenha em mente que, embora a rolagem seja bastante eficiente, uma janela grande pode ocupar uma quantidade razoável dememory.

4. Paginação com Hibernate usando a API Criteria

Finalmente, vamos olhar paraa more flexible solution - usando critérios:

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

A API de consulta de critérios do Hibernate torna muito simples tambémget the total count - usando um objetoProjection:

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

Como você pode ver, usar essa API resultará em um código minimamente mais detalhado do que o HQL simples, masthe API is fully type safe and a lot more flexible.

5. Conclusão

Este artigo é uma introdução rápida às várias maneiras de fazer paginação no Hibernate.

A implementação deste tutorial Spring JPA pode ser encontrada emthe GitHub project - este é um projeto baseado em Eclipse, então deve ser fácil de importar e executar como está.