grails / hibernate条件如何获取至少有一个子会议条件的所有行

时间:2017-01-10 18:52:50

标签: hibernate grails hibernate-criteria

我的理解是嵌套的子查询过滤子项。不是父母。换句话说

  Parent.withCriteria{
           children{
               gt('age', 5)
           }

  } 

将返回所有父母,但仅返回超过5岁的父母的子女。

使用这个例子作为参考,我想要的只是让至少有一个5岁以上的孩子的父母,并让所有孩子为这些父母。

我需要这个等效的查询是......

  SeasonDetails.withCriteria{
            not{
                clubHistory{
                    club{
                        eq('division',division);
                    }
                }
            }
    }

我只获得与某个俱乐部无关的赛季细节。

HQL的工作方式不同吗?也许我需要走那条路线

1 个答案:

答案 0 :(得分:1)

string query="""select new map(p as parent, c as children) from Parent p left join p.children c where c.age > :ageLimit"""
def inputParams=[:]
inputParams.ageLimit = 5
def results = Parent.executeCriteria(query,inputParams)
result?.each { r ->
   println "${r?.parent?.id} is parent id "
   r?.children?.eachWithIndex { c, i ->
    println "${c.id} ${c.age} is iteration ${i}"
   }
}
上面的

应该是HQL中的一个查询来执行您需要的操作,此时它正在返回map中的整个对象。这可能是昂贵的并且导致不必要的查找,(当在上面迭代时必须连接并再次获取它)

你可以做什么而不是捕捉你所需要的一切,并使用groupBy来获得你所需要的......

     string query="""select new map(p.name as parentName, p.id as parentId
 , c.id as childId, c.age as childAge, c.name as childName) from Parent p 
left join p.children c where c.age > :ageLimit"""

如果ids名称和年龄符合您的要求,现在应该返回您需要的所有内容的平面列表。现在你有每个父母的子女数量,所以如果父1有6个孩子,它会重复两次(正如你在上面的迭代中看到的那样)

你可以使用groupBy

def finalList = results.groupBy{it.parentId}

现在,这将把上面的列表更改为包含每个子项作为列表迭代的每个父组。

hql也有小组,你可能需要四处看看哪种方式最适合你。

查询1和查询2之间的主要区别在于,迭代时的查询1仍将与数据库交互以返回实际对象。在query2中,您将所有结果作为平面迭代返回,并且不再连接到实际的真实数据库对象。如果启用SQL调试,您将看到第二种方法的工作量减少了多少。