标准 API 按不同 children 的属性筛选
Criteria API filter by properties of different children
同时获得至少一个名为 'A' 的 Sub 和至少一个名为 'B' 的 Sub 的 Parent 的更好方法是什么?
我必须使用 Criteria API 来解决问题。
我有这样的具有 Many-To-Many 关系的实体(省略了一些代码):
class Parent {
Long id;
@ManyToMany
List<Sub> Subs
}
class Sub {
Long id
String name;
@ManyToMany
List<Parent> Parents
}
我会使用两个内部联接作为过滤器,这样就不必实现如下复杂的 where 子句:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Parent> cq = cb.createQuery(Parent.class);
Root<Parent> parent = cq.from(Parent.class);
Join<Parent,Sub> joinA = parent.join(parent.get("subs"),JoinType.INNER);
joinA.on(cb.equals(joinA.get("name"),"A"));
Join<Parent,Sub> joinB = parent.join(parent.get("subs"),JoinType.INNER);
joinB.on(cb.equals(joinB.get("name"),"B"));
cq.distinct(true);
cq.select(parent);
List<Parent> result = entityManager.createQuery(cq).getResultList();
如果您使用 2.1 之前的 JPA 版本,您将无法在 JOIN 中使用 ON 子句,因此您必须在 where 中实现谓词,如下所示(其和示例):
List<Predicate> predicates = new ArrayList<Predicate>();
predicates.add(cb.equals(joinA.get("name"),"A"));
predicates.add(cb.equals(joinB.get("name"),"B"));
cq.where(predicates.toArray(new Predicate[predicates.size()]));
同时获得至少一个名为 'A' 的 Sub 和至少一个名为 'B' 的 Sub 的 Parent 的更好方法是什么?
我必须使用 Criteria API 来解决问题。
我有这样的具有 Many-To-Many 关系的实体(省略了一些代码):
class Parent {
Long id;
@ManyToMany
List<Sub> Subs
}
class Sub {
Long id
String name;
@ManyToMany
List<Parent> Parents
}
我会使用两个内部联接作为过滤器,这样就不必实现如下复杂的 where 子句:
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Parent> cq = cb.createQuery(Parent.class);
Root<Parent> parent = cq.from(Parent.class);
Join<Parent,Sub> joinA = parent.join(parent.get("subs"),JoinType.INNER);
joinA.on(cb.equals(joinA.get("name"),"A"));
Join<Parent,Sub> joinB = parent.join(parent.get("subs"),JoinType.INNER);
joinB.on(cb.equals(joinB.get("name"),"B"));
cq.distinct(true);
cq.select(parent);
List<Parent> result = entityManager.createQuery(cq).getResultList();
如果您使用 2.1 之前的 JPA 版本,您将无法在 JOIN 中使用 ON 子句,因此您必须在 where 中实现谓词,如下所示(其和示例):
List<Predicate> predicates = new ArrayList<Predicate>();
predicates.add(cb.equals(joinA.get("name"),"A"));
predicates.add(cb.equals(joinB.get("name"),"B"));
cq.where(predicates.toArray(new Predicate[predicates.size()]));