Question

Je ne parviens pas à écrire une requête pour les classes de domaine suivantes:

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

En gros, je veux fonder toutes les personnes qui appartiennent à une liste de groupes (disons que les identifiants de groupe sont (1,2) . L'astuce ici est que la personne doit être membre des deux Je préférerais une requête de critères, mais HQL est également correct.

Notez que l'interrogation avec quelque chose comme group.id dans (1,2) ne fonctionnera pas car il peut s'agir de l'un des groupes, pas de les deux .

Était-ce utile?

La solution

C'est mon approche HQL simple:

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

A bientôt

Autres conseils

Peut-être que vous n'avez pas besoin d'une requête. Dans la classe Personne, les appartenances sont une liste d'objets d'adhésion. Vous pouvez rechercher si un objet est dans une collection (liste) sans effectuer de requête. Quelque chose comme ça devrait faire l'affaire.

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

L’autre solution est probablement plus simple, mais je pense que ce n’est qu’une autre option.

A bientôt

Collections Groovy

Problème intéressant. Pas sûr que les solutions précédentes soient génériques sur le nombre de groupes appariés - dans les cas précédents, il est fixé à 2 je pense. Bien qu'il y ait probablement un moyen de les rendre variables.

Une autre façon que je décris ici sur le tableau de bord de Grails - http://www.nabble.com/has-many-through-relationship-query---GORM--td23438096.html

Y compris les commentaires de l'auteur, Robert Fischer, sur "Grails Persistence with GORM et GSQL".

@chadsmall

Voici une autre approche qui évite de devoir ajouter par programme des sous-requêtes à votre clause WHERE:

Requête:

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)

Et quelques exemples de valeurs:

[
  groupIds: [8,9,439,86843]
  numOfGroupIds: 4
]

La partie de cette requête jusqu’à GROUP BY saisit toutes les personnes qui correspondent à n’importe quel groupe. Ensuite, en regroupant par personne et en vérifiant que le nombre de résultats est égal au nombre de groupes de la liste, vous pouvez vérifier que cette personne est membre de tous les groupes spécifiés.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top