2017-03-26 2 views
4

J'utilise Spring JPA.Spring JPA Spécification avec Tri

Pour être plus précis j'utilise un référentiel qui s'étend JpaRepository et JpaSpecificationExecutor parce que j'ai besoin de la pagination, du filtrage et du tri.

Maintenant, j'ai la pagination et le filtrage tout fonctionne très bien, mais je ne peux pas faire fonctionner le tri aussi bien.

je remarque avec une certaine déception que JpaSpecificationExecutor a findAll() méthodes:

findAll(Specification, Pageable); 
findAll(Specification, Sort); 

Mais celui que je besoin:

findAll(Specification, Pageable, Sort); //or something like this 

n'existe pas! Par conséquent, Plan B, incluez le tri dans la spécification.

Avec l'aide de la réponse acceptée à cette question: JpaSpecificationExecutor JOIN + ORDER BY in Specification je mets ensemble les éléments suivants:

private Specification<MainEntity> matches() { 
    return new Specification<MainEntity>() { 

     public Predicate toPredicate(Root<MainEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) { 

      List<Predicate> predicates = new ArrayList<Predicate>(); 

      //Attempt to sort by Surname, has no effect 
      query.orderBy(cb.asc(root.get("surname"))); 

      //add string filters 
      for (String field : stringFilterMap.keySet()) { 
       String valuePattern = stringFilterMap.get(field); 
       predicates.add(cb.like(root.get(field), "%"+valuePattern+"%")); 
      } 

      //...snip... 

      return cb.and(predicates.toArray(new Predicate[predicates.size()])); 
     } 
    };  
} 

springFilterMap est un champ d'instance, Map<String,String> dont les clés sont les noms de champs et les valeurs sont des valeurs de filtres. Ci-dessus, vous verrez ma tentative de commande par nom de famille, mais cela semble n'avoir aucun effet.

Qu'est-ce que je fais de mal? & Comment puis-je atteindre le tri avec la pagination et le filtrage?

+0

cela vous dérange en utilisant spring query dsl. vous n'avez pas besoin d'écrire du code pour le tri. suivez doc printemps ou je peux donner une direction. je l'ai utilisé et cela évite explicitement le codage supplémentaire. vous venez de passer vos paramètres et asc/desc, il vous donne le résultat approprié – surya

+0

J'ai rencontré votre question lorsque vous cherchez un problème similaire. J'utilise le référentiel dans mon contrôleur, et lorsque vous utilisez un contrôleur, vous pouvez utiliser '@PageableDefault (size = 10, sort =" sortColumn ", direction = Sort.Direction.DESC) Pageable pageable' dans votre signature de méthode pour obtenir un Objet Pageable rempli automatiquement (comme @PathVariable par exemple). – evandongen

Répondre

7

Utilisez PageRequest, qui est une implémentation de Pageable, et implémente la pagination et le tri en même temps, comme vous le souhaitez. Par exemple à travers this constructor:

public PageRequest(int page, int size, Sort sort)