如何查询一个M:N的关系与JPA2?(How to query an M:N relationshi

2019-06-25 23:50发布

我有一个物体(博文),它包含一个M:元件(标签)将N集合。

如何查询的对象(博客帖子),其中至少一个其它的标签元件与JPA2(休眠)的一组标签的(由用户定义)匹配。

findBlogPostWithAtLeastOneMatchingTag(Collection<Tag> tags){ ???? }

我的主要问题是,我其实需要比较的标签两个集合: - 的博客帖子标签的集合。 - 收集我搜索

我试图Select p from Post p where p.tags in(:tags) ,但它不工作,因为我的岗位实体已经不仅仅是一个标签了。

所以,我能做什么呢?

我的博文实体看起来是这样的。 它有几个标签。

@Entity
public class BlogPost{

    /** The tags. */
    @ManyToMany()
    @NotNull
    private Set<Tag> tags;

    @NotBlank
    private String content;

    ...
}

该解决方案必须不JPQL,JPA准则(不休眠准则)将被罚款了。

Answer 1:

如果你喜欢JPA标准,这是你的解决方案:

List<Integer> myTagsIds = new ArrayList<Integer> ();
myTagsIds.add(1);
myTagsIds.add(2);

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<BlogPost> cq = cb.createQuery(BlogPost.class);
Root<BlogPost> blogPost = cq.from(BlogPost.class);
SetJoin<BlogPost, Tag> tags = blogPost.join(BlogPost_.tags);
Predicate predicate = tags.get(Tag_.id).in(myTagsIds);
cq.distinct(true);
cq.where(predicate);
TypedQuery<BlogPost> tq = em.createQuery(cq);
return tq.getResultList();

该解决方案利用了的规范元模型类BlogPost_Tag_应该由你的JPA实现产生。



Answer 2:

方法1:

在SQL它可能是这样的:

SELECT p FROM Post p WHERE (p.tags INTERSECT :tags IS NOT EMPTY);

然后应用@SqlResultSetMapping

方法2:

您可以使用Criteria API ,并开始为你做,但做一个遍历Collection<Tag> tags为:

* make a union of single query results from `Select p from Post p where p.tags in(:tags)`;
* take distinct over result of union.

查询将被服务器端,你会不会做脏活在Java中。



Answer 3:

你可以这样做

从后t其中t.tag在选择T(从柱P选择p.tag其中p.id =:id)的

id是当前帖子的ID。 基本上你与那些在当前岗位的标签标签选择岗位。



文章来源: How to query an M:N relationship with JPA2?