一尘不染

JPA CriteriaBuilder-如何使用“ IN”比较运算符

hibernate

您能帮我如何将以下代码转换为使用条件生成器的“ in”运算符吗?我需要使用“ in”使用用户名列表/数组进行过滤。

我还尝试使用JPA CriteriaBuilder-“ in”方法进行搜索,但是找不到很好的结果。
因此,如果您能给我该主题的参考URL,我也将不胜感激。谢谢。

这是我的代码:

//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

阅读 2152

收藏
2020-06-20

共1个答案

一尘不染

如果我没有理解好了,你想加入ScheduleRequestUser和适用in条款的userName实体的财产User

我需要在该架构上进行一些工作。但是您可以尝试使用此技巧,该技巧比您发布的代码更具可读性,并且避免使用该Join部分(因为它处理Join了Criteria
Query之外的逻辑)。

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逻辑添加到中Criteria Query。但是现在我无法对其进行测试,因此我更愿意看看其他人是否想要尝试。

2020-06-20