1

У меня есть пара сценариев, в которых я хочу получить один Advertiser и получить большую часть своего графа объектов. Я определенно не хочу делать это по умолчанию, поэтому я искал правильный способ сделать это для одного запроса. Это то, что я придумал до сих пор:Есть ли более чистый, более Grailsy способ написать этот запрос?

Advertiser.createCriteria().get { 
     eq('id', id) 
     createAlias('foos', 'foos', CriteriaSpecification.LEFT_JOIN) 
     createAlias('foos.bars', 'bars', CriteriaSpecification.LEFT_JOIN) 
     createAlias('bars.baz', 'bazzes', CriteriaSpecification.INNER_JOIN) 
    } 

Это работает, но я не люблю его по нескольким причинам.

  1. Похоже, что это очень косвенный и неинтуитивный способ сказать «просто присоединитесь к столам Данг».
  2. Нет проверки времени компиляции. Если ассоциация foos не существовала на Advertiser, компилятору все равно.

Вот как я бы очень хотелось видеть, что это работает:

Advertiser.where { 
    id == id 
    foos { 
     bars { 
      baz 
     } 
    } 
} 

Но это не делает ни присоединения; очевидно, если вы на самом деле не задаете условия для этого свойства (>, <, == и т. д.), это просто проигнорирует вас.

Какие у меня варианты? Как я могу, как минимум, сделать это более понятным для чтения? В поисках ближайшего к моему идеалу, как я могу получить.

Редактировать

Я пробовал некоторые из предложений ниже, и вещи не работают, и это может быть отчасти потому, что я не получаю мой синтаксис права. Допустим, что мне нужно стремятся принести дополнительная первая ассоциация уровня называется whatsits

Я пытаюсь сделать это следующим образом:

Advertiser.withCriteria { 
    idEq(id) 
    whatsits 
    foos { 
     bars { 
      baz 
     } 
    } 
} 

Я также попытался

Advertiser.withCriteria { 
    idEq(id) && whatsits && foos { 
     bars { 
      baz 
     } 
    } 
} 

Но разный подходы дают разные исключения, странные запросы и т. д.

ответ

0

Это не слишком далеко от вашего первого примера, но вы можете или не можете найти его более интуитивно понятным ?

def result = Advertiser.withCriteria { 
    eq('id', id) 
    fetchMode 'foos', FetchMode.JOIN 
    fetchMode 'foos.bars', FetchMode.JOIN 
    fetchMode 'bars.baz', FetchMode.JOIN 
} 
+0

Вопрос использует 1 INNER_JOIN и 2 LEFT_JOINs. FetchMode.JOIN приведет к 3 INNER JOINs. –

0

Вы можете использовать DSLs в createCriteria/withCriteria, как вы использовали в пункте where, они по умолчанию eagerly извлечённому. Вы получаете результат как список, поэтому result[0] должен быть этим.

def result = Advertiser.withCriteria { 
    idEq(id) 
    foos{ 
     bars{ 
      baz{ 

      } 
     } 
    } 
} 

После получения результата обратно вы можете проверить, есть ли у вас ассоциации нет, то есть,

if(result[0].foos){...}

UPDATE

см это Sample Code для деталей.

UPDATE2

&&, ||, == не может быть использован в качестве критерия. Они имеют выделенные DSL для тех же операций, что и and{}, or{}, eq(). Посмотрите на Grails Criteria

Advertiser.withCriteria { 
    idEq(id) 
    whatsits{} 
    foos { 
     bars { 
      baz 
     } 
    } 
} 
+0

Есть ли способ рассказать об этом только для получения одного объекта, например 'createCriteria(). Get' делает в моем примере? – Samo

+0

В приведенном выше случае он будет извлекать только один объект, поскольку мы извлекаем его из первичного ключа 'id'. Не так ли? Вы можете использовать 'createCriteria(). Get' получить тот же результат, что и сам объект, а не как список одного объекта. – dmahapatro

+0

Кроме того, это не работает. Я получаю «Нет такого свойства: foos для класса: grails.orm.HibernateCriteriaBuilder» – Samo

Смежные вопросы