【问题标题】:query that should return entities qith specific related entities应返回具有特定相关实体的实体的查询
【发布时间】:2014-10-22 18:09:51
【问题描述】:

我认为通常我的问题很简单,但是我找不到一个好的解决方案。假设我有一个名为MyEntity 的实体类,它与一个名为EntityAttribute 的实体类有一个OneToMany 关系,所以它有一个包含此类对象的列表或集合attributesEntityAttribute 具有 name 类型的属性 String

现在我想实现一种方法,该方法采用属性名称并返回包含attributes 中每个名称的所有实体,至少一个具有该名称的属性。虽然这听起来很简单,但我发现的唯一解决方案是对每个属性名称执行查询并合并结果,如下所示:

for (String name : attributeNames) {
  CriteriaQuery<MyEntity> cq = cb.createQuery(MyEntity.class);
  Root<MyEntity> entity = cq.from(MyEntity.class);
  Join<MyEntity, EntityAttribute> attributeJoin = entity.join(MyEntity_.attributes);
  cq.where(attributeJoin.get(EntityAttribute_.name).equals(name));
  cq.select(entity);
  ... // get result list and merge
  }

此代码未经测试,但通常是一种解决方案。这似乎不是最有效的。 我测试的另一个解决方案是使用多个连接,例如

CriteriaQuery<MyEntity> cq = cb.createQuery(MyEntity.class);
Root<MyEntity> entity = cq.from(MyEntity.class);
List<Predicate> predicates = new ArrayList<>();
for (String name : attributeNames) {
  Join<MyEntity, EntityAttribute> attributeJoin = entity.join(MyEntity_.attributes);
  predicates.add(attributeJoin.get(EntityAttribute_.name).equals(name));
}
cq.select(predicates.toArray(new Predicate[] {}));
... // get result list

这似乎更有效,但它迭代笛卡尔积......所以它非常低效。

我也可以想象嵌套子查询,但这似乎很复杂。

问题很简单:这个问题的最佳解决方案是什么?之后我还想实现 AND 和 OR,所以我可以查询具有属性 x 和(y 或 z)或类似属性的所有实体。但现在我只想做 AND 案例。
提前致谢

【问题讨论】:

    标签: java jpa criteria-api


    【解决方案1】:

    如果我正确理解您的问题,也许您可​​以使用 in 子句 + group by + having + count 来实现这一点。这个想法是计算每个 MyEntity 的匹配数。如果计数等于传入的属性数,则意味着为该实体找到了每个属性(假设它们是唯一的)。在 JPQL 中,查询如下所示:

    select e from MyEntity e join e.attributes a
    where a.name in (:attributeNames)
    group by e having count(*) = :attributeCount
    

    其中:attributeCountattributeNames.size() 的值。

    我对条件 API 不是很熟悉,但您可以尝试以下方法:

    ...
    cq.groupBy(entity);
    cq.having(cb.equal(cb.count(entity), attributeNames.size()));
    // TODO: add IN clause
    ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-23
      • 1970-01-01
      相关资源
      最近更新 更多