2009-12-04 1 views
8

Я уверен, что кто-то, знакомый с HQL (я сам новичок), может легко ответить на этот вопрос.Как запросить дату в HQL (Hibernate) с Joda Time?

В моем приложении Grails у меня есть следующий класс домена.

class Book { 
    org.joda.time.DateTime releaseDate //I use the PersistentDateTime for persisting via Hibernate (that use a DATETIME type for MySQL DB) 
} 

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

Например, я попробовал:

DateTime date1, date2 
... 
def queryStr = "select * from Book as b where b.releaseDate > $date1 and b.releaseDate < $date2" 
def res = Book.executeQuery(queryStr) 

Но я получил исключение ...caused by: org.springframework.orm.hibernate3.HibernateQueryException: unexpected token: Формат маркеров ошибок в формате даты (например, 2009-11-27T21:57:18.010+01:00 или Fri Nov 27 22:01:20 CET 2009)

Я также попытался преобразовать дату1 в класс даты без успеха

Так что же такое правильный код HQL? Должен ли я конвертировать в конкретный формат (какой?) С использованием метода patternForStyle или есть другой способ очистки?

Thanks,

Fabien.

+0

Как карта org.joda.time.DateTime на ваш SQL? Это прямо на поле? java.util.Date и java.util.Calendar могут непосредственно сопоставляться с полем базы данных. Для чего это стоит, так как DateTime является агрегированным объектом, плагин Grails, вероятно, использует под обложками настраиваемый тип сопоставления (см. Раздел 5.3 Java Persistence with Hibernate). – Alan

+0

Как указано в комментарии к коду, DateTime использует настраиваемый тип сопоставления PersistentDateTime из библиотеки joda-time-hibernate – fabien7474

ответ

7

Я не эксперт Grails, но в Java вы обычно делают date1 и date2 параметры запроса и связать их как таковые:

String hql = "select * from Book as b where b.releaseDate > :date1 and b.releaseDate < :date2"; 
session.createQuery(hql).setDate("date1", date1).setDate("date2", date2).list(); 

Я уверен, что вы можете сделать что-то подобное в Grails. Если нет, отформатируйте свои даты как yyyyMMddhhmmss (без пробелов) и заключите их в одинарные кавычки - таким образом Hibernate будет рассматривать их как константы, а MySQL будет неявно преобразовывать их в даты.

+0

Большое спасибо! После вашего ответа я отправился в исходный код Grails и нашел это для выполнения запросов HQL: Account.executeQuery («выберите отдельный номер a.number из учетной записи a, где a.branch =: branch ", [branch: 'London']) Так что я сделал то же самое для своего сценария, и это сработало. Thx. – fabien7474

5

Я указал на ChssPly, вы должны объявить date1 и date2 как параметры запроса (позиционные или названные), а затем связать их. Здесь мы будем использовать именованные параметры. Обычный способ передать именованные параметры запроса с Grails осуществляется через Map:

def queryStr = "from Book b where b.releaseDate > :date1 and b.releaseDate < :date2" 
Book.executeQuery(queryStr, [date1: date1, date2: date2]) 

Проверить executeQuery() документация синтаксических деталей обоих вариантов.

+0

Hi Pascal Thx для вашей помощи. Я сделал именно то, что вы написали. – fabien7474

3

Вы также можете сравнить даты, используя ISO8601 формат даты например:

select * from Book as b 
where b.releaseDate > '2009-11-27T21:57:18.010+01:00' 
and b.releaseDate < '2010-11-27T21:57:18.010+01:00' 

Я проверил это с помощью MySql в задней части. Не забудьте обернуть даты в виде строки.

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