我在编写以下域类的查询时遇到问题:
class Person {
static hasMany = [memberships: Membership]
}
class Membership {
static belongsTo = [person: Person, group: Group]
Date joinDate = new Date();
Group group;
Person person;
}
class Group {
static hasMany = [memberships: Membership]
}
基本上,我想找到属于一个群组列表的所有人(假设群组ID为(1,2)
。这里的诀窍是该人必须是两个群组的成员。我更喜欢条件查询,但HQL也可以。
请注意,查询group.id in (1,2)
之类的内容无效,因为它可以是任何群组,而不是 。
答案 0 :(得分:1)
这是我简单的HQL方法:
Person.executeQuery("FROM Person x WHERE x IN (SELECT m.person from Membership m WHERE m.group = :group1) AND x IN (SELECT m.person from Membership m WHERE m.group = :group2)", [ group1: Group.get(1), group2: Group.get(2) ])
干杯
答案 1 :(得分:0)
也许您不需要查询。在Person类中,成员资格是Membership对象的列表。您可以在不进行任何查询的情况下查找对象是否在Collection(列表)中。 这样的事情应该可以胜任。
if(Person.memberships.contains(Membership.findByPersonAndGroup(person1,group1)) && Person.memberships.contains(Membership.findByPersonAndGroup(person1,group2))){
...do something...
}
可能另一种解决方案更简单,但我认为这只是另一种选择。
干杯
答案 2 :(得分:0)
有趣的问题。不确定以前的解决方案是否在匹配组的数量上是通用的 - 在目前为止的情况下,我认为它固定为2。虽然可能有一种方法可以使它们变量。
我在grails留言板上描述的另一种方式 - http://www.nabble.com/has-many-through-relationship-query---GORM--td23438096.html
包括作者Robert Fischer的评论,“Grails Persistence with GORM and GSQL”。
@chadsmall
答案 3 :(得分:0)
这是另一种避免必须以编程方式将子查询附加到WHERE子句的方法:
查询:
SELECT count(person.id) AS numPeople, person
FROM Person as person
INNER JOIN
person.memberships AS mships
WITH mships.group.id IN (:groupIds)
GROUP BY person.id
HAVING COUNT(person.id) = (:numOfGroupIds)
一些示例值:
[
groupIds: [8,9,439,86843]
numOfGroupIds: 4
]
此查询到GROUP BY的部分将抓取所有匹配任何组的人员。然后,通过按人分组并检查结果数等于列表中的组数,您可以验证此人是否是所有指定组的成员。