java - 应返回具有特定相关实体的实体的查询

标签 java jpa criteria-api

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

现在我想实现一种方法,该方法采用属性名称并返回对于 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 案例。
提前致谢

最佳答案

如果我正确理解你的问题,也许你可以使用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
...

关于java - 应返回具有特定相关实体的实体的查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26514219/

相关文章:

java - 单击按钮时 Android Activity 崩溃

java - 单击时尝试更改 JButton 上的图标

java - 使用 play-framework 2.2.x 删除对象时违反参照完整性约束

java - 带有列表的 JPA CriteriaQuery 投影

java - 仅 CriteriaBuilder 最大日期

java - 删除 Java 中的 dakuten/handakuten(又名十-十,ぱ→は)

java - 不同的 long 值产生相同的时间

jpa - 如何对 JPA 查询的子查询施加 LIMIT?

java - 使用 JPA 的 Apache Server Servlet 上出现 NullPointerException

java - 真正动态的 JPA CriteriaBuilder