簡體   English   中英

如何查詢與JPA2的M:N關系?

[英]How to query an M:N relationship with JPA2?

我有一個對象(BlogPost),它包含一個M:N元素集合(標簽)。

如何查詢一個對象(BlogPost),其中至少有一個對象的標簽與一組標簽(由用戶定義)中的元素與JPA2(Hibernate)匹配。

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

我的主要問題是,我實際上需要比較兩個標簽集合: - BlogPost的標簽集合。 - 我搜索的集合

我嘗試Select p from Post p where p.tags in(:tags)但它不起作用,因為我的帖子實體只有一個標簽。

那我該怎么做呢?

我的BlogPost實體看起來像這樣。 它有幾個標簽。

@Entity
public class BlogPost{

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

    @NotBlank
    private String content;

    ...
}

解決方案不能是JPQL,JPA-Criteria(不是Hibernate-Criteria)也可以。

如果你喜歡JPA Criteria,這就是你的解決方案:

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();

此解決方案使用應由JPA實現生成的規范MetaModelBlogPost_Tag_

方法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中進行臟工作。

你可以做點什么

從Post t中選擇t,其中t.tag in(從post p中選擇p.tag,其中p.id =:id)

id是當前帖子的ID。 基本上,您選擇的帖子中包含當前帖子標簽中的標簽。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM