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