2 回答
TA贡献1812条经验 获得超5个赞
没有内置的或特别漂亮的方法来做到这一点。但是您可以使用循环生成查询:
public List<Event> getByNameAndLocationAndDate(List<Event> events) {
if (events.isEmpty()) {
return new ArrayList<>();
}
final StringBuilder queryBuilder = new StringBuilder("select e from Event e where ");
int i = 0;
for (final Event event : events) {
if (i > 0) {
queryBuilder.append("or")
}
queryBuilder.append(" (e.name = :name" + i);
queryBuilder.append(" and e.location = :location" + i);
queryBuilder.append(" and e.date = :date" + i + ") ");
i++;
}
final TypedQuery<Event> query = em.createQuery(queryBuilder.toString());
int j = 0;
for (final Event event : events) {
query.setParameter("name" + j, event.getName());
query.setParameter("location" + j, event.getLocation());
query.setParameter("date" + j, event.getDate());
}
return query.getResultList();
}
就像我说的,不是很漂亮。使用标准 API 可能会更好。再说一次,除非您对执行速度有非常严格的要求,否则最好一次遍历列表检查一个事件。这将导致对数据库运行更多的查询,但也会产生更漂亮的代码。
编辑:这是使用标准 API 的尝试,还没有使用它太多,所以只是通过谷歌搜索创建的,不能保证它按原样工作..
public List<Event> getByNameAndLocationAndDate(List<Event> events) {
if (events.isEmpty()) {
return new ArrayList<>();
}
final CriteriaBuilder cb = em.getCriteriaBuilder();
final CriteriaQuery<Event> query = cb.createQuery(Event.class);
final Root<Event> root = query.from(Event.class);
final List<Predicate> predicates = new ArrayList<>();
final List<Predicate> predicates = events.stream().map(event -> {
return cb.and(cb.equal(root.get("name"), event.getName()),
cb.equal(root.get("location"), event.getLocation()),
cb.equal(root.get("date"), event.getDate()));
}).collect(Collectors.toList());
query.select(root).where(cb.or(predicates.toArray(new Predicate[]{})));
return em.createQuery(query).getResultList();
}
TA贡献1851条经验 获得超3个赞
尝试
List<Event> findByNameInAndLocationInAndDateIn(List<String> names,List<String> locations,List<Date> dates);
但这将返回一个列表,而不是单个事件,如果您需要验证一个事件是否不在数据库中,唯一的方法是逐一搜索,您可以使用此函数来决定是否需要。
我不确定这个功能是否如你所愿
添加回答
举报