2009-10-21 4 views
8

Comment implémenter la pagination dans Hibernate? Les objets Query ont des méthodes appelées setMaxResults et setFirstResult qui sont certainement utiles. Mais où puis-je obtenir le nombre total de résultats, de sorte que je peux montrer le lien à la dernière page de résultats, et imprimer des choses telles que les résultats 200 à 250 de xxx?Implémentation de la pagination des résultats dans hibernate (obtention du nombre total de lignes)

+1

Je suis d'accord avec les deux autres réponses. En outre, je demande des pratiques de mise en œuvre dans ce poste: http://stackoverflow.com/questions/1600440/java-coding-best-practices-for-reusing-part-of-a-query-to-count – KLE

Répondre

12

Vous pouvez utiliser Query.setMaxResults (résultats int) et Query.setFirstResult (décalage int).

Édition aussi: Il n'y a aucun moyen de savoir combien de résultats vous obtiendrez. Donc, vous devez d'abord interroger avec "select count (*) ...". Un peu moche, à mon humble avis.

1

Vous pouvez effectuer deux requêtes - une requête de type count (*), qui devrait être bon marché si vous ne joignez pas trop de tables ensemble, et une deuxième requête qui a les limites définies. Ensuite, vous savez combien d'éléments existent mais ne saisissent que ceux qui sont affichés.

-2

Personnellement, je pense que vous devriez gérer le paging dans le front-end. Je sais que ce n'est pas très efficace, mais au moins, il serait moins sujette aux erreurs.

Si vous utilisiez la fonction count (*), que se passerait-il si les enregistrements étaient supprimés de la table entre les demandes d'une page donnée? Beaucoup de choses pourraient mal tourner de cette façon.

+0

I ne pense pas que c'est critique. Si les enregistrements sont supprimés ** et ** vous pouvez parcourir les dernières pages, vous recevrez une erreur plus un lien vers les derniers enregistrements existants. Ou quelque chose de similaire. – flybywire

+3

il y a des problèmes avec la pagination sur le frontal si la quantité de données est prohibitivement grande - disons, 1 million d'enregistrements ou quelque chose. – Chii

7

Vous devez faire une requête séparée pour obtenir le maximum de résultats ... et dans le cas où entre le temps A du premier moment où le client envoie une requête de pagination à l'heure B lorsqu'une autre requête est émise, si de nouveaux enregistrements sont ajoutés ou certains enregistrements correspondent maintenant aux critères, alors vous devez interroger le maximum à nouveau pour en tenir compte. Je fais habituellement ceci dans HQL comme ce

Integer count = (Integer) session.createQuery("select count(*) from ....").uniqueResult(); 

pour Criteria requêtes Je pousse habituellement mes données dans un DTO comme celui-ci

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

Vous pouvez seulement setMaxResults au nombre maximum de lignes que vous souhaitez renvoyer. Il n'y a aucun inconvénient à définir cette valeur plus grande que le nombre de lignes réelles disponibles. Le problème des autres solutions est qu'elles supposent que l'ordre des enregistrements reste le même à chaque répétition de la requête, et qu'il n'y a pas de changement entre les commandes. Pour éviter cela si vous voulez vraiment faire défiler les résultats, il est préférable d'utiliser ScrollableResults. Ne jetez pas cet objet entre la pagination, mais utilisez-le pour conserver les enregistrements dans le même ordre. Pour connaître le nombre d'enregistrements de ScrollableResults, vous pouvez simplement passer à la position last(), puis obtenir le numéro de ligne. N'oubliez pas d'ajouter 1 à cette valeur, car les numéros de ligne commencent à compter à 0.

Questions connexes