有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java查询,该查询应返回特定相关实体的实体

一般来说,我的问题很简单,但我没有找到一个好的解决方案。假设我有一个名为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)或类似属性的所有实体。但现在我只想说明情况
提前谢谢


共 (1) 个答案

  1. # 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()的值

    我不太熟悉criteria API,但您可以尝试以下内容:

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