Implementar resultado paginação em hibernação (ficando número total de linhas)
Pergunta
Como faço para implementar paginação em hibernação? A Query
objetos tem métodos chamados setMaxResults
e setFirstResult
que são certamente útil. Mas onde eu posso obter o número total de resultados, para que eu possa mostrar link para última página de resultados, e imprimir coisas como resultados 200 a 250 de xxx ?
Solução
Você pode usar Query.setMaxResults (resultados int) e Query.setFirstResult (int offset).
Edição demais: Não há nenhuma maneira de saber quantos resultados você vai conseguir. Então, primeiro você deve consultar com "SELECT COUNT (*) ...". Um pouco feio, IMHO.
Outras dicas
Você deve fazer uma consulta separada para obter os resultados max ... e no caso em que entre o tempo A da primeira vez que os problemas do cliente um pedido de paginação para o tempo B quando outro pedido for emitido, se novos registros são adicionados ou alguns registros agora se ajustam aos critérios então você tem que consultar o máximo novamente para refletir tal. Eu costumo fazer isso em HQL como este
Integer count = (Integer) session.createQuery("select count(*) from ....").uniqueResult();
para consultas Criteria
I normalmente empurrar meus dados em um DTO como este
ScrollableResults scrollable = criteria.scroll(ScrollMode.SCROLL_INSENSITIVE);
if(scrollable.last()){//returns true if there is a resultset
genericDTO.setTotalCount(scrollable.getRowNumber() + 1);
criteria.setFirstResult(command.getStart())
.setMaxResults(command.getLimit());
genericDTO.setLineItems(Collections.unmodifiableList(criteria.list()));
}
scrollable.close();
return genericDTO;
Você poderia executar duas consultas - uma consulta count (*) Tipo, que deve ser barato se você não está unindo muitas tabelas juntos, e uma segunda consulta que tem os limites estabelecidos. Então você sabe quantos itens existe mas apenas agarrar as que estão sendo visualizado.
Você pode apenas setMaxResults para o número máximo de linhas que deseja retornado. Não há mal nenhum em definir este valor maior que o número de linhas reais disponíveis. O problema das outras soluções é que eles assumem a ordenação de registros permanece o mesmo a cada repetição da consulta, e não há mudanças em curso entre os comandos.
Para evitar que se você realmente quer percorrer os resultados, é melhor usar os ScrollableResults. Não jogue este objeto afastado entre paginação, mas usá-lo para manter os registros na mesma ordem. Para descobrir o número de registros das ScrollableResults, você pode simplesmente mover para a última posição (), e em seguida, obter o número da linha. Lembre-se de adicionar 1 a este valor, uma vez que números de linha iniciar a contagem em 0.
Eu, pessoalmente, acho que você deve lidar com a paginação no front-end. Eu sei que isso não é tão eficiente, mas pelo menos seria menos propenso a erros.
Se você usar o count (*) coisa que poderia acontecer se os registros são excluídos da mesa entre solicitações para uma determinada página? Muitas coisas podem dar errado neste caminho.