java查询,该查询应返回特定相关实体的实体
一般来说,我的问题很简单,但我没有找到一个好的解决方案。假设我有一个名为MyEntity
的实体类,它与名为EntityAttribute
的实体类有一个OneToMany关系,因此它有一个带有此类对象的列表或集合attributes
EntityAttribute
有一个类型为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 楼答案
如果我正确理解你的问题,也许你可以使用
in
子句+group by
+having
+count
来实现这一点。这个想法是计算每个MyEntity的匹配数。如果计数等于传入的属性数,则表示为该实体找到了每个属性(假设它们是唯一的)。在JPQL中,查询如下所示:其中
:attributeCount
是attributeNames.size()
的值我不太熟悉criteria API,但您可以尝试以下内容: