2013-01-07 6 views
1

Je suis en train de créer des recherches avec différents filtres. Comme j'utilise JpaRepository pour faire des requêtes simples, j'ai trouvé le JpaSpecificationExecutor pour faire des requêtes dynamiques avec les Criterias.JpaSpecificationExecutor: requêtes complexes avec spécifications

Mon problème est que je dois créer une requête complexe avec un groupe by et un count(). C'est bon pour le groupe mais je ne trouve pas comment je peux contourner la partie "select" pour mettre une instruction "count".

Quelqu'un peut-il m'aider s'il vous plaît?

J'utilise le printemps 3.1.2 et les données JPA-printemps 1.0.3 Voici mon code:

return new Specification<Article>() { 

    @Override 
    public Predicate toPredicate(final Root<Article> root, 
     final CriteriaQuery<?> query, final CriteriaBuilder builder) { 
     //count ??? 
     query.groupBy(root.get(Article_.id)); 
     Predicate p = builder.and(builder.like(root.<String> get(Article_.title), "%" + title + "%")); 

     return p; 
    } 
} 

Merci! Si vous regardez le org.springframework.data.jpa.repository.support.SimpleJpaRepository de Spring Data il y a une méthode appelée getCountQuery(..)

Répondre

3

Malheureusement vous ne pouvez pas le faire avec la spécification ressort données.

Vous pouvez voir pourquoi et comment pour le faire en utilisant encore des données ressort ici (il y a une requête simple retour un seul champ): spring-data specifications - return list of ids instead of objects

Pour obtenir une liste des champs que vous pouvez utilisez JPA Tuple. Vous trouverez un exemple ici: JPA & Criteria API - Select only specific columns

Version courte: Vous devez créer un référentiel ressort données personnalisé qui utilisera CriteriaQuery<Tuple>.

+1

Merci pour votre aide. J'ai choisi de faire deux demandes. Un pour obtenir tous mes identifiants avec la spécification. La seconde (le compte) avec une requête simple qui correspond à mes identifiants. – user1838850

1

cette requête ressemble à ceci:

/** 
* Creates a new count query for the given {@link Specification}. 
* 
* @param spec can be {@literal null}. 
* @return 
*/ 
private TypedQuery<Long> getCountQuery(Specification<T> spec) { 

    CriteriaBuilder builder = em.getCriteriaBuilder(); 
    CriteriaQuery<Long> query = builder.createQuery(Long.class); 

    Root<T> root = applySpecificationToCriteria(spec, query); 
    query.select(builder.count(root)); 

    return em.createQuery(query); 
} 

cela est utilisé dans le composant le paginable du printemps de données JPA et peut fournir une solution

+1

Bonjour, merci pour votre réponse, mais cette méthode ne fait que compter. Comment est-ce que je peux faire un querylike "choisir un.value, count (un.id) d'un groupe par un.value"? – user1838850

+0

Spring Data JPA, comme le mentionne rchukh, peut effectuer des requêtes personnalisées complètes. Si vous avez déjà l'instruction SQL, vous pouvez demander au gestionnaire d'entités de l'exécuter en tant que NativeQuery, puis de mapper les résultats sur un objet vous-même. –