0

私は2つのエンティティを持っています:

  1. エンジニア - タグのセットがあります (たとえば、スキルセット - Java. .NET など)
  2. 鬼ごっこ

エンジニアは、任意の数のタグを持つことができます。タグは、任意の数のエンジニアに関連付けられます。

@Entity
public class Engineer implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    @Column(nullable = false, length = 12)
    private String id;

    @Column(length = 100)
    private String name;

    @OneToMany(fetch = FetchType.EAGER)
    List<Tag> tags;

    /* Getters and Setters */
}

@Entity
public class Tag implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    private int id;

    @Column(length = 50)
    private String name;

    /* Getters and Setters */
}

ここで、関連付けられたタグのリストを持っているエンジニアを照会したいと思います。たとえば、「「Java」、「Opensource」、「Banking」というタグを持つエンジニアのクエリ」。クエリは、関連付けられたすべてのタグを持つエンジニアを返す必要があります。

1 つのタグを照会できます。

public List<Engineer> searchMindsByTags(String tag) {
    Query q = em.createQuery("SELECT e FROM Engineer e WHERE '" + tag
            + "' = ANY(SELECT tag.name FROM e.tags tag)");
    return (List<Engineer>) q.getResultList();
}

私が必要とするのは:

public List<Engineer> searchMindsByTags(List<String> tags) {
    /* Which query goes here? */
}

この仕事を行うことができる単一のクエリはありますか、それともフィルタリングするために結果を段階的に反復する必要がありますか?

4

3 に答える 3

1

エンジニアは、任意の数のタグを持つことができます。タグは、任意の数のエンジニアに関連付けられます。

エンティティの設計が上記の要件と矛盾しています。

Tag と 1 対多の関係を持つ Engineer をモデル化しました。したがって、タグ テーブルには外部キー列が表示されますengineer_id。つまり、タグは 1 人の (そして 1 人だけの) エンジニアに関連付けられます。

結合テーブルを使用して、多対多の関係をモデル化する必要があります。Engineer エンティティ クラスには で装飾された Tag コレクションが必要@ManyToManyです。Tag エンティティ クラスには で装飾された Engineer コレクションが必要@ManyToManyです。

Tag クラスで Engineer コレクションを使用すると、searchMindsByTags関数を実装できます

于 2013-09-10T07:01:03.660 に答える
0

私の頭に浮かぶ最初のことは、次のようなものでクエリを作成できるということです:

public List<String> searchMindsByTags(List<String> tags)
{

    String queryString = "SELECT e FROM Engineer e ";
    List<Tag> tagobjects=null;
    if (tags != null && !tags.isEmpty()) {
        Query q = entityManager.createQuery("Select t from tag t where t.name IN :tags");
        q.setParameter("tags", tags);
        tagobjects = q.getResultList();
        queryString += " WHERE ";
        for (int i = 0; i < tagobjects.size(); i++) {
            if (i != 0) {
                queryString += "AND ";
            }
            queryString += "?" + (i + 1) + " member of e.tags";
        }
    }
    Query q = entityManager.createQuery(queryString);
    if (tagobjects != null && !tagobjects.isEmpty()) {
        for (int i = 0; i < tagobjects.size(); i++) {
            q.setParameter((i + 1), tagobjects.get(i));
        }
    }
    return (List<Engineer>) q.getResultList();
}

その簡単な例には、いくつかのテストが必要です。

于 2013-09-10T09:19:42.180 に答える