Получение объекта с наибольшим значением члена в hql? - PullRequest
4 голосов
/ 24 мая 2010

Я все еще немного новичок в hql, и у меня возник вопрос о функциях агрегирования и эффективности запроса, который я пишу.

Допустим, у меня этот класс отображается в hibernate (методы getters / setters / constructors / etc. Опущены для краткости):

public class Foo
{
    private int i;

    private String s;

    private float f;
}

Я хочу выполнить hql-запрос, чтобы получить экземпляр Foo с наибольшим значением i и указанными значениями s & f. Мое текущее решение таково:

List<Foo> fooList = (List<Foo>)session.createQuery(
    "from Foo as foo where foo.s = :str and foo.f = :val order by foo.i desc").
    setParameter("str", <stringgoeshere>).setParameter("val", <floatgoeshere>).
    list();
return fooList.get(0);

Если я правильно понимаю, у этого метода будет N + 1 выбор проблемы (хотя, пока я получаю только первый результат из списка, N, будем надеяться, будет 1, но все же) , Я предполагаю, что есть какой-то способ сделать это с uniqueResult (), но я не совсем понимаю, как функции агрегации будут работать в этом случае. Единственные примеры, в которых я смог найти "max ()", находятся либо в предложении where, либо в возвращаемом значении.

Как мне написать этот запрос, чтобы выполнить его за один выбор, и получить экземпляр Foo с самым высоким значением i?

Спасибо за помощь!

1 Ответ

2 голосов
/ 25 мая 2010

Если я правильно понимаю, у этого метода будет проблема выбора N + 1

Я не вижу, как ваш запрос может привести к выбору n + 1.У Hibernate нет оснований для итерации по результатам первого запроса и выполнения последующих запросов здесь.

Я предполагаю, что есть какой-то способ сделать это с uniqueResult (), но я не совсем понимаю, как функции агрегации будут работать в этом случае.

ЕслиЕсли вы хотите получить один результат, было бы разумно , а не получить всю таблицу.Во-первых, запрос будет более эффективным, а во-вторых, вы не собираетесь тратить память впустую (и, возможно, даже заставите Session взорваться).Что если ваша таблица содержит миллион записей?

Как мне написать этот запрос, чтобы выполнить его за один выбор и получить экземпляр Foo с самым высоким значением i?

Как только что упоминалось, получить только нужную запись, используйте setMaxResults(1), чтобы ограничить количество результатов (это сгенерирует правильный порядок SQL в зависимости от вашей базы данных):

Foo foo = (Foo) session.createQuery(
    "from Foo as foo where foo.s = :str and foo.f = :val order by foo.i desc")
    .setParameter("str", <stringgoeshere>).setParameter("val", <floatgoeshere>)
    .setMaxResults(1)
    .uniqueResult();
return foo;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...