我正在尝试为我的 Java Web 应用程序实现某种数据过滤机会。 在我的例子中,用户应该能够过滤那些客户,例如出生于 12 月 2 日之后并且 clientSate 处于 ACTIVE 或 INCATIVE 状态的客户。 就我而言,ACTIVE 和 INACTIVE 是枚举值。
由于用户可以选择 2 或 3 甚至 5 种不同的状态,我这样做:
for (EnumValue enumValue : constraint.getValues().getEnumValue()) {
ClientState state = ClientState.valueOf(enumValue.getValue());
predicate = builder.or(builder.equal(client.get(constraint.getField().getValue()), state));
}
但它不起作用。
这是我的完整功能代码:
public List<Client> getClients(List<FilterConstraint> filters) {
try {
CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<?> mainQuery = builder.createQuery(Client.class);
Root<Client> client = mainQuery.from(Client.class);
Predicate predicate = builder.conjunction();
for (FilterConstraint constraint : filters) {
switch (constraint.getOperator()) {
case AFTER:
predicate = builder.and(builder.greaterThan(client.get(constraint.getField().getValue()), constraint.getValues().getStartDate()));
break;
case BEFORE:
predicate = builder.and(builder.greaterThan(client.get(constraint.getField().getValue()), constraint.getValues().getStartDate()));
break;
case BETWEEN:
if (constraint.getField().getType() == FieldDataType.DATE) {
predicate = builder.and(builder.between(client.get(constraint.getField().getValue()), constraint.getValues().getStartDate(), constraint.getValues().getEndDate()));
} else {
predicate = builder.and(builder.between(client.get(constraint.getField().getValue()), constraint.getValues().getMinValue(), constraint.getValues().getMaxValue()));
}
break;
case EMPTY:
predicate = builder.and(builder.isEmpty(client.get(constraint.getField().getValue())));
break;
case EQUALS:
if (constraint.getField().getType() == FieldDataType.ENUM) {
if (constraint.getValues().getEnumValue().size() > 1) {
for (EnumValue enumValue : constraint.getValues().getEnumValue()) {
ClientState state = ClientState.valueOf(enumValue.getValue());
predicate = builder.or(builder.equal(client.get(constraint.getField().getValue()), state));
}
break;
}
ClientState state = ClientState.valueOf(constraint.getValues().getEnumValue().get(0).getValue());
predicate = builder.or(builder.equal(client.get(constraint.getField().getValue()), state));
break;
}
predicate = builder.and(builder.equal(client.get(constraint.getField().getValue()), constraint.getValues().getValue()));
break;
case LESS_THAN:
case MORE_THAN:
case NOT_EMPTY:
case ON:
case STARTS_WITH:
case TODAY:
}
}
CriteriaQuery<Long> cq = builder.createQuery(Long.class);
cq.select(builder.count(cq.from(Client.class)));
em.createQuery(cq);
cq.where(predicate);
Long count = em.createQuery(cq).getSingleResult();
mainQuery.where(predicate);
//TODO Pagination Result should be returned
TypedQuery<?> q = em.createQuery(mainQuery);
List<Client> allClients = (List<Client>) q.getResultList();
return allClients;
} catch (Exception e) {
System.out.println(e.getMessage());
return null;
}
}
我进行了很多搜索,但无法资助 OR 运算符没有确切值的示例 - 实际上我发现比较 2 个值或 3 个值 - 而不是更多。
有人可以告诉我如何修复我的代码以便能够支持 OR 表达式中的任意数量的值吗?
最佳答案
CriteriaBuilder.or
接受谓词数组。因此,只需创建一个“等于枚举值”谓词数组并调用 or
该数组一次。
或者,您可能需要考虑in <enum values>
相反。
关于java - Criteria API - OR 比较器,比较次数未知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40963234/