Как сделать это коротким в Grails или Hibernate - PullRequest
0 голосов
/ 08 октября 2011

У меня есть запрос, который выглядит примерно так:

SomeDomain.executeQuery("""
    from
        SomeDomain x
    where
        x.linkToSomeA = coalesce(:a, x.linkToSomeA) and
        x.linkToSomeB = coalesce(:b, x.linkToSomeB) and
        ...
    """,
    [a: someA, b: someB, ...]
)

Предполагаемое поведение следующее: если для параметра критерия задано null, этот критерий следует игнорировать. Если указано что-то отличное от null, используется критерий.

Все будет работать нормально, за исключением того, что Hibernate не позволяет поставлять null там, где ожидаются экземпляры класса домена. Таким образом, в конце концов, это неправильный запрос (на самом деле NullPointerException будет выдан, если будет предоставлено null s).

Я не нашел способа переписать это без использования тонны if-else. Кто-нибудь знает, как сделать так, чтобы было одинаково кратким и действительным одновременно?

ПРИМЕЧАНИЕ: реальный запрос более сложен, чем этот, поэтому, пожалуйста, не предлагайте переписать его, используя что-либо еще, кроме executeQuery.

Ответы [ 2 ]

3 голосов
/ 08 октября 2011

Обычно для такого рода проблем используется API Criteria: он позволяет динамически создавать запрос:

Criteria c = session.createCriteria(SomeDomain.class, "x");
if (a != null) {
    c.add(Restrictions.eq("x.linkToSomeA", a));
}
if (b != null) {
    c.add(Restrictions.eq("x.linkToSomeB", b));
}
// ...

Этот ответ не следует вашей просьбе не использовать ничего, кроме executeQuery, но вы также можете спросить, как построить дом, используя только отвертку, и лучшим ответом все равно будет "купить другие инструменты". «).

1 голос
/ 10 октября 2011

Мне интересно, можете ли вы использовать карту и findAll(), например:

def query = [
    'a': 'x.linkToSomeA = :a',
    'b': 'x.linkToSomeB = :b'
].findAll{ k, q -> params[k] != null }.values().join(' and ')

SomeDomain.executeQuery("""
    from
        SomeDomain x
    where
        ${query}
    """,
    params
)

Это должно вернуть список всех элементов запроса, которые имеют ненулевые параметры в карте параметров (это должно быть изменено, чтобы соответствовать карте, используемой в запросе). Это простая задача фильтрации на основе «ключа» главной карты, а затем объединение значений с помощью and.

Заметьте, есть одна потенциальная проблема, и это если вообще нет параметров. В этом случае вы захотите проверить, что query не пусто или предоставить запасной метод.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...