2013-04-26 98 views
1

你好,我试图获得域对象的列表,如果域对象的hasmany关联包含给定列表中的所有元素。检查域类'hasmany集合是否包含子集集合

class Patient { 
    static hasMany = [symptoms:Symptom] 
} 
class Symptom { 
} 

寻找类似containsAll()的东西,但可以在标准的使用将是真棒。但我自己找不到。我希望标准将让我这样做:

Patient.createCriteria().list { 
    'containsAll'('symptoms',listOfSymptoms) 
} 
+0

如果运行与列表语句而不是listDistinct查询,它的工作原理?只是为了检查问题出在哪里。 – lucke84 2013-04-26 11:56:23

+0

是的最后一段代码的工作原理和它应该做的。问题是我无法找到相当于list.containsAll(subset) – 2013-04-26 13:31:14

回答

0

这可以在HQL来完成(更简洁),并肯定存在标准不containsAll功能。

Patient.executeQuery(
"FROM Patient p WHERE p IN 
(SELECT s.patient from Symptom s WHERE s.id = :id1) 
AND p IN 
(SELECT s.patient from Symptom s WHERE s.id = :id2) 
AND p IN 
(SELECT s.patient from Symptom s WHERE s.id = :id3)", 
[id1: 1, id2: 2, id3: 3]) 
+0

的条件表达式谢谢。但我如何构建这个查询,如果我只是一个集合('List'或'Set')'ID' – 2013-04-28 15:54:12

0

已找到一种方法来做到没有标准或hql。但是我不知道当Patient表拥有数百万行数据时会发生什么。它可能会变得丑陋。

Patient.list().findAll{ 
    it.symptoms.containsAll(listOfSymptoms) 
} 

或ID可以像这样使用:

Patient.list().findAll{ 
    it.symptoms*.id.containsAll(listOfSymptomIds) 
} 
+0

我无法说服自己建议你在这里做同样的事情。在这种情况下复杂性增加。 '.list()'遍历整个表并返回所有行,'findAll'遍历所有行,'sympt * .id'遍历所有'症状',最后'containsAll'破坏其余行。 :)。我本可以提出相同的建议,但我希望您的应用程序在没有饥饿的情况下生存。 :)尝试将几千条记录添加到“Patient”和“Symptom”,并查看其差异。 – dmahapatro 2013-04-28 16:07:37

+0

是的,它的工作速度很慢:D。你能告诉我如何用给定的'id'列表构造查询字符串吗? – 2013-04-30 11:33:08