2

次のエンティティがあります。

@Entity
public class Article{
    @Id
    private String id;

    @ManyToMany(cascade = CascadeType.PERSIST)
    private Set<Tag> tags;

//non-relevant code
}

@Entity 
public class Tag{
    @Id
    private String id;

    @Basic
    @Column(nullable = false, unique = true, length = 32)
    private String name;

//non-relevant code
}

共通のタグArticleを持つすべてのエンティティを効率的に見つけるにはどうすればよいですか?set

単純なアプローチは、それぞれに属するすべての記事を見つけてから、すべての記事セットの をtag返すことです。intersection何かのようなもの:

public Set<Article> findByTags(Set<Tag> tags){
    Set<Article> result = new HashSet<>();

    if(tags.isEmpty()){
        return result;
    }

    Iterator<Tag> i = tags.iterator();
    result.addAll(i.next().getArticles());

    while(i.hasNext() && !result.isEmpty()){
        result.retainAll(i.next());
    }

    return result;
}

私の質問は、「このような DB からおそらくすべての記事を取得する必要がない、これを行うためのより効率的な方法はありますか? JPQL クエリを使用するか、CriteriaBuilder(以前は使用したことがありません)」

4

1 に答える 1

6
select a from Article a where :numberOfTags = 
    (select count(distinct tag.id) from Article a2
     inner join a2.tags tag
     where tag in :tags
     and a = a2)

これは基本的に、受け入れられたタグのセットのタグである記事のタグをカウントし、そのようなタグの数が受け入れられたタグのセットのサイズと等しい場合 (セット内のすべてのタグが記事のタグであることを意味します) 、記事を返します。

于 2014-02-08T11:40:01.513 に答える