【问题标题】:Criteria API filter by properties of different childrenCriteria API 按不同子项的属性过滤
【发布时间】:2021-06-24 16:19:14
【问题描述】:

让一个父级同时拥有至少一个名为“A”的子和至少一个名为“B”的子的更好方法是什么?

我必须使用 Criteria API 来解决问题。

我有这种具有多对多关系的实体(省略了一些代码):

class Parent {
    Long id;

    @ManyToMany
    List<Sub> Subs

}
class Sub {
    Long id

    String name;

    @ManyToMany
    List<Parent> Parents
}

【问题讨论】:

    标签: java criteria-api


    【解决方案1】:

    我会使用两个内连接作为过滤器,这样就不必像下面这样实现复杂的 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()]));
    

    【讨论】:

      猜你喜欢
      • 2011-08-31
      • 1970-01-01
      • 1970-01-01
      • 2014-12-01
      • 2018-07-04
      • 2011-10-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多