【问题标题】:Check if domain class' hasmany collection contains the subset collection检查域类的 hasmany 集合是否包含子集集合
【发布时间】:2013-04-20 10:43:35
【问题描述】:

您好,如果域对象的 hasmany 关联包含给定列表中的所有元素,我正在尝试获取域对象列表。

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

寻找类似于containsAll() 但可以在标准中使用的东西会很棒。但我自己找不到。我希望标准能让我这样做:

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

【问题讨论】:

  • 如果您使用 list 语句而不是 listDistinct 运行查询,它是否有效?只是为了检查问题出在哪里。
  • 是的,最后一段代码可以正常工作并且完全按照它应该做的那样工作。问题是我找不到 list.containsAll(subset) 的标准表达式的等价物

标签: hibernate grails grails-orm criteria grails-2.0


【解决方案1】:

这可以在 HQL 中完成(不太冗长),是的,Criteria 中没有 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])

【讨论】:

  • 谢谢。但是,如果我只有 ids 的集合(ListSet),我该如何构造这个查询
【解决方案2】:

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

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

或者id可以这样使用:

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

【讨论】:

  • 我无法说服自己向您推荐与您在这里所做的相同的事情。在这种情况下,复杂性会增加。 .list() 遍历整个表并返回所有行,findAll 再次遍历所有行,symptoms*.id 遍历所有symptoms,最后containsAll 销毁其余部分。 :)。我本可以提出相同的建议,但我希望您的应用程序能够在没有饥饿的情况下生存。 :) 尝试将数千条记录添加到 PatientSymptom 并查看差异。
  • 是的,它的工作速度非常缓慢:D。你能告诉我如何用给定的ids 列表构造那个查询字符串吗?
猜你喜欢
  • 2017-06-04
  • 1970-01-01
  • 1970-01-01
  • 2015-01-30
  • 1970-01-01
  • 2022-01-04
  • 1970-01-01
  • 2019-09-02
相关资源
最近更新 更多