JPA CriteriaBuilder-comment utiliser l'opérateur de comparaison "IN"

<!-Pouvez-vous m'aider à convertir les codes suivants en utilisant l'opérateur "in" de criteria builder? Je dois filtrer en utilisant list / array des noms d'utilisateurs en utilisant "in".

j'ai aussi essayé d'utiliser la méthode JPA CriteriaBuilder - "in" Mais je n'ai pas trouvé de bon résultat. J'apprécierais donc vraiment aussi si vous pouvez me donner des URLs de référence pour ce sujet. Grâce.

Voici mes codes:

//usersList is a list of User that I need to put inside IN operator 

CriteriaBuilder builder = getJpaTemplate().getEntityManagerFactory().getCriteriaBuilder();
CriteriaQuery<ScheduleRequest> criteria = builder.createQuery(ScheduleRequest.class);

Root<ScheduleRequest> scheduleRequest = criteria.from(ScheduleRequest.class);
criteria = criteria.select(scheduleRequest);

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

List<ParameterExpression<String>> usersIdsParamList = new ArrayList<ParameterExpression<String>>();

for (int i = 0; i < usersList.size(); i++) {
ParameterExpression<String> usersIdsParam = builder.parameter(String.class);
params.add(builder.equal(scheduleRequest.get("createdBy"), usersIdsParam) );
usersIdsParamList.add(usersIdsParam);
}

criteria = criteria.where(params.toArray(new Predicate[0]));

TypedQuery<ScheduleRequest> query = getJpaTemplate().getEntityManagerFactory().createEntityManager().createQuery(criteria);

for (int i = 0; i < usersList.size(); i++) {
query.setParameter(usersIdsParamList.get(i), usersList.get(i).getUsername());
}

List<ScheduleRequest> scheduleRequestList = query.getResultList();

la chaîne de requête interne est convertie en ci-dessous, donc je ne reçois pas les enregistrements créés par les deux utilisateurs, parce qu'il utilise "et".

select generatedAlias0 from ScheduleRequest as generatedAlias0 where ( generatedAlias0.createdBy=:param0 ) and ( generatedAlias0.createdBy=:param1 ) order by generatedAlias0.trackingId asc 
35
demandé sur xenteros 2012-02-17 05:59:25

2 réponses

Si je comprends bien, vous voulez vous Joindre à ScheduleRequestUser et appliquer les in clause userName propriété de l'entité User.

j'aurais besoin de travailler un peu sur ce schéma. Mais vous pouvez essayer avec ce truc, c'est beaucoup plus lisible que le code que vous avez posté, et évite les Join part (parce qu'il gère le Join logique à l'extérieur de la Requête de Critères).

List<String> myList = new ArrayList<String> ();
for (User u : usersList) {
    myList.add(u.getUsername());
}
Expression<String> exp = scheduleRequest.get("createdBy");
Predicate predicate = exp.in(myList);
criteria.where(predicate);

pour écrire plus de code de sécurité, Vous pouvez aussi utiliser Metamodel le remplacement de cette ligne:

Expression<String> exp = scheduleRequest.get("createdBy");

avec ceci:

Expression<String> exp = scheduleRequest.get(ScheduleRequest_.createdBy);

Si cela fonctionne, alors vous pouvez essayer d'ajouter le Join logique dans le Criteria Query. Mais pour l'instant je ne peux pas le tester, donc je préfère voir si quelqu'un d'autre veut essayer.

75
répondu perissf 2012-02-19 18:19:48

ce n'est pas une réponse parfaite même si des bribes de code pourraient aider.

public <T> List<T> findListWhereInCondition(Class<T> clazz,
            String conditionColumnName, Serializable... conditionColumnValues) {
        QueryBuilder<T> queryBuilder = new QueryBuilder<T>(clazz);
        addWhereInClause(queryBuilder, conditionColumnName,
                conditionColumnValues);
        queryBuilder.select();
        return queryBuilder.getResultList();

    }


private <T> void addWhereInClause(QueryBuilder<T> queryBuilder,
            String conditionColumnName, Serializable... conditionColumnValues) {

        Path<Object> path = queryBuilder.root.get(conditionColumnName);
        In<Object> in = queryBuilder.criteriaBuilder.in(path);
        for (Serializable conditionColumnValue : conditionColumnValues) {
            in.value(conditionColumnValue);
        }
        queryBuilder.criteriaQuery.where(in);

    }
13
répondu baba.kabira 2012-02-17 05:05:58