2016-02-13 75 views
1

我有两个实体。例如,帖子和标签。 我必须编写一个方法,该方法仅包含查询中提到的具有所有标签的帖子。HQL检查对象是否包含请求集的所有元素 - 重复

我试图

@Query("select distinct p from posts p join p.tags t where t in ?1") 
Page<Post> findDistinctByTagsIn(Set<Tag> tagSet, Pageable pageable); 

但是它需要后,如果包含在其标签集标记中的至少一个。

如何仅使用HQL和JPA存储库解决此问题?

@ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL) 
@JoinTable(name = "posts_tags", joinColumns = { 
     @JoinColumn(name = "post_id", nullable = false, updatable = false)}, 
     inverseJoinColumns = {@JoinColumn(name = "tag_id")}) 
public Set<Tag> getTags() { 
    return tags; 
} 

回答

1

您的帖子必须组,并仅选择职位,其中匹配的记录计数等于传入的标签的数量(即所有标签比赛):

select p from Posts p join p.tags t 
where t in :tags 
group by p 
having count(p) = :tagsSize 

但是,你有额外的tagsSize参数来传递与tagSet.size()值。

你可以改变你的资料库的方法签名接受这个PARAM并调用这样的方法:

repo.findDistinctByTagsIn(tagSet, tagSet.size(), Pageable pageable); 

,为避免冗余,后来将其更改为使用规划环境地政司表达时Spring adds support for it

@Query("select p from Posts p join p.tags t where t in :tags " 
    + "group by p having count(p) = :#{#tags.size()}") 
Page<Post> findDistinctByTagsIn(@Param("tags") Set<Tag> tagSet, Pageable pageable); 

或者,无论如何,由于查询变得稍微复杂一些,您可以直接使用EntityManager以单独的方法创建它,并手动设置所需的参数,以便您不强制方法的客户端为b e意识到查询语义细节。

+0

谢谢,它的工作原理! –

-1

应该有TAGS表的主键。

我们可以将主键的一组标签对象传递给NamedParameter查询,然后您只获取映射到标签对象的Post对象。

您必须针对多对多对象编写查询。

示例: query = SELECT mm.post FROM POST_TAG_MM mm WHERE mm.tag.primarykeycolumn in(:postPrimaryKeySet);

查询q = s.getNamedQuery(query); q.setParameterList(“postPrimaryKeySet”,tagsPrimyKeySet);

请让我知道如果您有任何疑问

相关问题