是否可以帮助我如何将以下代码转换为使用条件构建器的“in”运算符? 我需要使用“in”使用列表/数组的用户名进行过滤。
我也尝试使用JPA CriteriaBuilder进行搜索 - “in”方法但是找不到好结果。 如果你能给我这个主题的参考网址,我也非常感谢。感谢。
这是我的代码:
//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();
内部查询字符串转换为下面,因此我不会获取两个用户创建的记录,因为它使用“AND”。
select generatedAlias0 from ScheduleRequest as generatedAlias0 where ( generatedAlias0.createdBy=:param0 ) and ( generatedAlias0.createdBy=:param1 ) order by generatedAlias0.trackingId asc
答案 0 :(得分:84)
如果我理解,您希望ScheduleRequest
加入User
并将in
子句应用于实体userName
的{{1}}属性。< / p>
我需要对这个架构进行一些工作。但是你可以尝试使用这个技巧,它比你发布的代码更具可读性,并避免使用User
部分(因为它处理Criteria Query之外的Join
逻辑)。
Join
为了编写更多类型安全的代码,您还可以通过替换此行来使用Metamodel:
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);
用这个:
Expression<String> exp = scheduleRequest.get("createdBy");
如果有效,则可以尝试将Expression<String> exp = scheduleRequest.get(ScheduleRequest_.createdBy);
逻辑添加到Join
。但是现在我无法测试它,所以我更愿意看看别人是否想尝试。
答案 1 :(得分:14)
虽然代码片段可能有所帮助,但不是一个完美的答案。
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);
}