Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java: Общие вопросы > hibernate запрос с участием коллекции


Автор: Samotnik 13.1.2011, 12:45
привет, нужен совет с составлением запроса.
Есть коллекция чисел  List<Long> categories  - в ней, допустим: 1,4,5,7,8,10,11. 
Вопрос как подставить в запрос эту коллекцию ? Неужели кроме как доставать по значению из коллекции и подставлять в запрос, других выходов нету ? Т.е. если 10 значений, то 10 раз вызывать метод ?

Автор: MisterCleric 13.1.2011, 12:51
Привет. 
Вот такое не подойдет?
Код

session.createQuery("from User where id in (:ids)")
                    .setParameterList("ids", ids, Hibernate.LONG)

Автор: Samotnik 13.1.2011, 12:54
MisterCleric, я так тоже думал, сделал

Код

public List<Message> getMessagesByTenant(List<Long> categories) throws SQLException {
  Session session = null;
  try {
    session = HibernateUtil.getSessionFactory().openSession();
    return session.createCriteria(Message.class).add(Restrictions.in("category.id", categories)).list();
  } finally {
    HibernateUtil.closeSession(session);
  }
    }


но почему-то пустая коллекция ...

Автор: MisterCleric 13.1.2011, 12:55
Покажи запрос, который при этом сгененрировался

Автор: Samotnik 13.1.2011, 13:07
MisterCleric, нет, извини, всё действительно работает, я случайно не те значения подставлял  smile 

Автор: Samotnik 14.1.2011, 00:55
Запрос существенно расширился, и я опять с вопросом на форум smile 
Задача примерно такая. Есть две таблицы.
Код

Category (
int id;
char name;
);
Message (
int id;
char text;
categori_id;
);
Delivery (
int id;
int id_message;
boolean sent;

Нужно выбрать сообщения, которые были отосланы, и которые небыли отосланы.
Для выбора отосланных сообщений я написал запрос:
Код

select ms from Delivery dy inner join dy.message as ms where dy.deleted=:deleted and dy.sent=:sent and ms.category.id in (:ids)

теперь нужно написать выборку для не отправленных сообщений, критерий такой: выбрать все записи из таблицы delivery у которых sent=false + все записи из message, которые не попали в delivery.  smile 
 smile 

Автор: MisterCleric 14.1.2011, 09:52
Привет. 
Стоп! Что-то я не сильно сегодня соображаю, или что-то ты перегибаешь.
Цитата

Нужно выбрать сообщения, которые были отосланы, и которые небыли отосланы.

В чем проблема? Ведь
 отосланные + не отосланные = ВСЕ
Не так ли? Или есть еще какие-то другие сообщения?
В чем суть задачи? Может действительно достаточно выбрать все, а на клиенте фильтровать их по соответствующему признаку. Ведь связка-то у тебя между Message и Delivery

Автор: Temdegon 14.1.2011, 16:27
Я так понял, что неотосланные сообщения добавляются в delivery с признаком sent=false, а могут и вообще не попасть в delivery и быть только в message.

Автор: MisterCleric 14.1.2011, 16:34
Temdegon

Не-не. Человек явно написал:
Цитата

все записи из message, которые не попали в delivery


Автор: Samotnik 14.1.2011, 17:34
MisterCleric, да, спасибо, ты меня натолкнул на мысль, я просто буду передавать флаг, какие сообщения нужно вернуть отосланные или нет. Если отосланные, то буду возвращать результат выборки, если нет, то буду общему результату делать removeAll() - куда передам результат выборки отосланных. Получится, что из общего результата удаляться отосланные, следовательно я получу список не отосланных, верно ? )

Автор: Temdegon 14.1.2011, 17:59
Тогда можно использовать условие
where ms.category.id NOT in (:ids)
и передать коллекцию отправленных

Автор: MisterCleric 14.1.2011, 18:13
Ну как я понял, можно решить на уровне запроса (правда нативного):
Код

SELECT m.* FROM MEssage m, Delivery d
WHERE m.id= d.messageId(+) AND nvl(d.send,false) = false


Автор: Samotnik 14.1.2011, 18:31
MisterClericTemdegon, т.е. то, что я написал не верно ? Без запроса не обойтись ?

Добавлено через 2 минуты и 4 секунды
Появилось новое условие  smile 
В таблице Message есть еще одно поле - время создания. Так вот, в метод будут приходить еще два параметра в виде Date dateFrom, Date dateTo, как в эту выборку что у меня есть, подставить еще эти две даты, т.е. чтобы сообщения были выбраны с учетом этого периода. smile
Код

select ms from Delivery dy inner join dy.message as ms 
   where dy.deleted=:deleted and dy.sent=:sent and ms.category.id in (:ids)

Автор: MisterCleric 14.1.2011, 18:49
between тебе в помощь.
Ну или зависит от inclusive/exclusive начала-конца периода.

Автор: Samotnik 14.1.2011, 18:51
MisterCleric, ага, я уже тоже нашел
Код

select ms from Delivery dy
    inner join dy.message as ms where dy.deleted=:deleted and dy.sent=:sent
    and ms.timestamp between :dateFrom and :dateTo
    and ms.category.id in (:ids)

так что на счет моего способа получать не отосланные сообщения ? : )

Автор: Temdegon 14.1.2011, 21:39
Цитата

Ну как я понял, можно решить на уровне запроса (правда нативного):

nvl это вроде оракловская функция. В хибере есть ее аналог - coalesce(a,b)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)