2017-01-10 3 views
0

Насколько я понимаю, вложенные подзапросы фильтруют дочерние элементы. а не родитель. Другими словамикритерии grails/hibernate, как получить все строки, у которых есть хотя бы одно условие встречи с ребенком

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

    } 

будет возвращать все родители, но только дети тех родителей, которые более 5.

Используя пример в качестве ссылки, что я хочу, чтобы получить только родители, которые имеют по крайней мере, одного ребенка в возрасте старше 5 лет и получить всех детей за этих родителей.

Запрос, который мне нужен этот эквивалент для это ...

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

, где я только получать детали сезона, которые не связаны с определенным клубом.

Работает ли HQL по-другому? Может быть, мне нужно идти по этому пути, вместо

ответ

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

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