如何通过多个值匹配多个值? (所有比赛)
对于以下示例,提供了标记,查询将返回所有匹配所有标记的文档。如何在JPA中做到这一点?感谢。
数据:
Document 1 : { id: 1, name: "doc1", tags: [1, 2] }
Document 2 : { id: 2, name: "doc2", tags: [2, 3] }
Tag 1 : { id: 1, name: "tag1" }
Tag 2 : { id: 2, name: "tag2" }
Tag 3 : { id: 3, name: "tag3" }
方案:
Criteria: "tag1", "tag2"
=> Return: "doc1"
Criteria: "tag1", "tag2", "tag3"
=> Return: Nothing
Criteria: "tag2"
=> Return: "doc1" and "doc2"
实体:
public class Document {
@Id
private Long id;
@Column
private String name;
@ManyToMany
@JoinTable(name = "DOCUMENT_TAG_RLAT")
private List<Tag> tags;
}
public class Tag {
@Id
private Long id;
@Column
private String name;
}
答案 0 :(得分:0)
我不知道完美的解决方案,但这会奏效:
public List<Document> documentsByTags(List<String> tagNames) {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Document> criteriaQuery = criteriaBuilder.createQuery(Document.class);
Root<Document> documents = criteriaQuery.from(Document.class);
List<Predicate> predicates = new ArrayList<Predicate>();
for (String tagName : tagNames) {
Subquery<Long> sq = criteriaQuery.subquery(Long.class);
Root<Tag> tags = sq.from(Tag.class);
sq.select(tags.<Long>get("documents")).where(
criteriaBuilder.equal(tags.get("name"), tagName);
predicates.add(criteriaBuilder.in(documents.<Long> get("id")).value(sq));
}
criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));
TypedQuery<Document> query = entityManager.createQuery(criteriaQuery);
return query.getResultList();
}
另外,在我看来,你需要双向关系@ManyToMany
(在你的Tag.class
属性上看不到文件,可能你只是没有粘贴),以及你的@JoinTable
注释你必须指定joinColumns和inverseJoinColumns。
答案 1 :(得分:0)
@paulek我没有尝试你的解决方案,但我想到了一个有效的解决方案。
select d from Document d
where
(select count(t) from d.tags as t, Tag t2 where t.id = t2.id and t2 in (:tags))
=
:tagCount