JPA Criteria builder IN clause query
如何为以下给定的JPQL查询编写条件构建器api查询?
我正在使用
1 2 3 4 | SELECT * FROM Employee e WHERE e.Parent IN ('John','Raj') ORDER BY e.Parent |
此标准设置应该可以解决问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<Employee> q = cb.createQuery(Employee.class); Root<Employee> root = q.from(Employee.class); q.select(root); List<String> parentList = Arrays.asList(new String[]{"John","Raj"}); Expression<String> parentExpression = root.get(Employee_.Parent); Predicate parentPredicate = parentExpression.in(parentList); q.where(parentPredicate); q.orderBy(cb.asc(root.get(Employee_.Parent)); q.getResultList(); |
我在这里使用了重载的
您还可以使用Criteria API In子句来执行此操作,如下所示:
1 2 3 4 5 6 7 8 9 10 11 | CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<Employee> cq = cb.createQuery(Employee.class); Root<Employee> root = cq.from(Employee.class); List<String> parentList = Arrays.asList("John","Raj"); In<String> in = cb.in(root.get(Employee_parent)); parentList.forEach(p -> in.value(p)); return entityManager .createQuery(cq.select(root) .where(in).orderBy(cb.asc(root.get(Employee_.Parent))) .getResultList(); |
为此和几乎所有可能的标准示例签出我的Github。
1 2 3 4 5 6 | List<String> parentList = Arrays.asList("John","Raj"); final CriteriaBuilder cb = entityManager.getCriteriaBuilder(); final CriteriaQuery<Employee> query = cb.createQuery(Employee.class); final Root<Employee> employee = query.from(Employee.class); query.select(employee).where(employee.get("Parent").in(parentList)); |
这应该工作正常。有关更多信息,请参阅baeldung的这篇文章。这是非常足智多谋的https://www.baeldung.com/jpa-criteria-api-in-expressions
我希望它会有用。在Entry只有一个@Id列的情况下测试了代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public static <Entry, Id> List<Entry> getByIds(List<Id> ids, Class<Entry> clazz, EntityManager entityManager) throws CustomDatabaseException { List<Entry> entries; try { CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<Entry> q = cb.createQuery(clazz); Root<Entry> root = q.from(clazz); EntityType<Entry> e = root.getModel(); CriteriaQuery<Entry> all = q.where(root.get(e.getId(e.getIdType().getJavaType()).getName()).in(ids)); TypedQuery<Entry> allQuery = entityManager.createQuery(all); entries = allQuery.getResultList(); } catch (NoResultException nre) { entries = Collections.emptyList() } catch (Exception e) { throw new CustomDatabaseException(e); } return entries; } |
当您需要使用Criteria API再次执行此操作时,请不要打断您-您可以为Dao创建一个父包装类,并在其中放置一个hepler方法:
1 2 3 4 5 6 7 8 9 10 11 12 | /** * An SQL"WHERE IN" expression alternative. * * @param inList List to search in. * @param pathToEntityField Path to a field in your entity object. * @return A ready predicate-condition to paste into CriteriaQuery.where(). */ @SuppressWarnings("unchecked") private Predicate in(List< ? > inList, Expression pathToEntityField) { return pathToEntityField.in(inList); } |
使用WHERE IN然后像这样:
1 | query.where(**in**(myList, root.get(MyTypedEntity_.id))); |