我有两个实体:
工程师可能有任意数量的标签。标签与任何数量的工程师都有关联。
@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‘、’开放资源‘和’银行‘的工程师”。查询应返回具有与其相关的所有标记的工程师。
我能够查询一个标签:
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? */
}
是否有一个查询可以完成此工作,还是需要对结果进行逐步迭代以进行筛选?
发布于 2013-09-10 07:01:03
工程师可能有任意数量的标签。标签与任何数量的工程师都有关联。
您的实体设计与上述要求相矛盾。
你模拟工程师有一对多的关系要标记。因此,在标记表上,您将看到一个外键列engineer_id
。Ie:标签与一名(也只有一名)工程师有关。
您需要使用join表来建模这种关系。Engineer实体类应该使用@ManyToMany
装饰标记集合,标记实体类应该有一个用@ManyToMany
装饰的Engineer集合。
使用标记类上的Engineer集合,您可以实现searchMindsByTags
函数
发布于 2013-09-10 09:19:42
我首先想到的是,您可以使用以下内容构造查询:
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-10 14:50:23
您可以使用多个子选择,也可以使用计数。
看,list
https://stackoverflow.com/questions/18711958
复制相似问题