首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JPA:查询列表中的所有项目,其中目标也是列表

JPA:查询列表中的所有项目,其中目标也是列表
EN

Stack Overflow用户
提问于 2013-09-10 06:21:54
回答 3查看 855关注 0票数 0

我有两个实体:

  1. Engineer -有一组标记(比如说技能集- Java )。( .NET等)
  2. 标签

工程师可能有任意数量的标签。标签与任何数量的工程师都有关联。

代码语言:javascript
运行
复制
@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‘、’开放资源‘和’银行‘的工程师”。查询应返回具有与其相关的所有标记的工程师。

我能够查询一个标签:

代码语言:javascript
运行
复制
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();
}

我需要的是:

代码语言:javascript
运行
复制
public List<Engineer> searchMindsByTags(List<String> tags) {
    /* Which query goes here? */
}

是否有一个查询可以完成此工作,还是需要对结果进行逐步迭代以进行筛选?

EN

回答 3

Stack Overflow用户

发布于 2013-09-10 07:01:03

工程师可能有任意数量的标签。标签与任何数量的工程师都有关联。

您的实体设计与上述要求相矛盾。

你模拟工程师有一对多的关系要标记。因此,在标记表上,您将看到一个外键列engineer_id。Ie:标签与一名(也只有一名)工程师有关。

您需要使用join表来建模这种关系。Engineer实体类应该使用@ManyToMany装饰标记集合,标记实体类应该有一个用@ManyToMany装饰的Engineer集合。

使用标记类上的Engineer集合,您可以实现searchMindsByTags函数

票数 1
EN

Stack Overflow用户

发布于 2013-09-10 09:19:42

我首先想到的是,您可以使用以下内容构造查询:

代码语言:javascript
运行
复制
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();
}

它的快速例子,需要一些测试。

票数 0
EN

Stack Overflow用户

发布于 2013-09-10 14:50:23

您可以使用多个子选择,也可以使用计数。

看,list

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18711958

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档