7 votes

Les critères JPA renvoient une page et un total

Pour des données paginées, j'ai besoin de retourner le nombre total d'enregistrements correspondant à mes critères et les résultats de la première page. Cela est utile pour afficher des informations aux utilisateurs et calculer le nombre total de pages à attendre (du côté client).

actuellement, j'exécute la même requête deux fois, une fois pour le décompte total et une fois pour les enregistrements réels. J'espère qu'il existe un moyen plus efficace.

est-il possible de combiner ces deux requêtes en un seul appel à la base de données ?

le décompte :

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery cq = cb.createQuery(Long.class);
    Root r = cq.from(VersionJpa.class);
    Predicate p = cb.conjunction();
    p = // some filtering code define by caller
    cq.where(p);
    cq.select(cb.count(r));
    TypedQuery tq = em.createQuery(cq);
    return tq.getSingleResult().intValue();

la page :

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery cq = cb.createQuery(VersionJpa.class);
    Root root = cq.from(VersionJpa.class);
    Predicate p = cb.conjunction();
    p = // same filtering code as in the count above
    cq.where(p);
    TypedQuery tq = em.createQuery(cq);
    // pagination
    tq.setFirstResults(first); // from caller
    tq.setMaxResults(max);     // from caller
    return tq.getResultList();

2voto

perissf Points 6899

Même en supposant qu'il existe une requête efficace qui récupère à la fois le nombre d'enregistrements et les enregistrements paginés eux-mêmes, vous auriez besoin d'effectuer un appel supplémentaire à la base de données pour chaque page consultée par l'utilisateur. Et cela rendrait négligeable le gain de performance obtenu lors de l'accès à la première page.

Je veux dire ce qui suit : pour accéder à la première page, vous avez besoin de :

  1. du nombre total d'éléments filtrés sans pagination
  2. des éléments filtrés avec pagination pour la page 1

Pour accéder aux autres pages, vous n'avez plus besoin de la requête de décompte. Vous avez seulement besoin des éléments filtrés pour la page x.

Après avoir déplié n pages, même en utilisant l'optimisation que vous recherchez, vous auriez effectué n appels au lieu des n+1 appels de la version non optimisée. Donc, je ne passerais pas trop de temps à réfléchir à cela.

Vous devez simplement faire attention, dans votre implémentation, à ne pas effectuer le décompte des enregistrements lorsqu'il n'est pas nécessaire : vous en avez besoin uniquement après que l'utilisateur ait modifié le filtre.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X