Проблема ассоциации запроса Grails - PullRequest
3 голосов
/ 05 мая 2009

У меня проблемы с написанием запроса для следующих классов домена:

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]
}

По сути, я хочу найти всех людей, которые относятся к списку групп (скажем, идентификаторы групп: (1,2). Хитрость в том, что человек должен быть членом обеих групп. Я бы предпочел критерий запроса , но HQL тоже подойдет.

Обратите внимание, что запросы с чем-то вроде group.id in (1,2) не будут работать, потому что это может быть любая из групп, а не обе .

Ответы [ 4 ]

1 голос
/ 06 мая 2009

Это мой простой 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) ])

Приветствия

0 голосов
/ 01 февраля 2012

Вот еще один подход, позволяющий избежать необходимости программно добавлять подзапросы к предложению 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 собирает всех людей, которые соответствуют любой групп. Затем, сгруппировав по человеку и проверив, что количество результатов равно числу групп в списке, вы можете проверить, что этот человек является членом всех указанных групп.

0 голосов
/ 12 мая 2009

Интересная проблема. Не уверен, что предыдущие решения являются общими для числа совпадающих групп - в тех случаях, на данный момент, оно установлено на 2, я думаю. Хотя, возможно, есть способ сделать их переменными.

Другой способ, который я опишу здесь на доске объявлений Grails - http://www.nabble.com/has-many-through-relationship-query---GORM--td23438096.html

Включая комментарий автора, Роберта Фишера, "Сохранение Grails с помощью GORM и GSQL".

@ chadsmall

0 голосов
/ 07 мая 2009

Может быть, вам не нужен запрос. В классе Person членство - это список объектов Членства. Вы можете определить, находится ли объект в коллекции (списке), не выполняя никаких запросов. Нечто подобное должно делать эту работу.

if(Person.memberships.contains(Membership.findByPersonAndGroup(person1,group1)) && Person.memberships.contains(Membership.findByPersonAndGroup(person1,group2))){
  ...do something...
}

Возможно, другое решение проще, но я думаю, что это просто еще один вариант.

Приветствия

Коллекции Groovy

...