English 中文(简体)
How to query a date in HQL (Hibernate) with Joda Time?
原标题:

I am sure that someone familiar with HQL (I am myself a newbie) can easily answer this question.

In my Grails application, I have the following domain class.

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

In my HQL query, I want to retrieve books whose release date is included in range date1..date2

For instance I tried:

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

But I got the exception ...caused by: org.springframework.orm.hibernate3.HibernateQueryException: unexpected token: The error token points to date format (for instance 2009-11-27T21:57:18.010+01:00 or Fri Nov 27 22:01:20 CET 2009)

I have also tried to convert date1 into a Date class without success

So what is the correct HQL code ? Should I convert to a specific format (which one?) using the patternForStyle method or is there another -cleaner- way to do it?

Thanks,

Fabien.

最佳回答

I m no Grails expert, but in java you d normally make date1 and date2 query parameters and bind them as such:

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();

I m sure you can do something similar in Grails. If not, format your dates as yyyyMMddhhmmss (no spaces) and enclose them in single quotes - that way Hibernate would treat them as constants and MySQL will implicitly convert them to dates.

问题回答

I pointed out by ChssPly, you should declare date1 and date2 as query parameters (positional or named) and then bind them. Here, we ll use named parameters. The usual way to pass named query parameters with Grails is via a Map:

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

Check executeQuery() documentation for the syntax details of both options.

You can also compare dates using the ISO8601 date format e.g:

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 

I ve tested this using MySql as the back end. Just remember to wrap the dates up as a string.





相关问题
Entity Framework with File-Based Database

I am in the process of developing a desktop application that needs a database. The application is currently targeted to SQL Express 2005 and works wonderfully. However, I m not crazy about having ...

Assistance with CakePHP model relationships

How would I represent the following in a CakePHP model? Product ======= product_id .... Cart ==== cart_id .... Carts_Products ============== cart_id product_id quantity

join across databases with nhibernate

I am trying to join two tables that reside in two different databases. Every time, I try to join I get the following error: An association from the table xxx refers to an unmapped class. If the ...

How are Models (in MVC) and DAOs supposed to interact?

How are models and DAOs supposed to interact? I m in the process of putting together a simple login module and I m unsure where to put the "business logic." If I put the logic with the data in the ...

Convert date to string upon saving a doctrine record

I m trying to migrate one of my PHP projects to Doctrine. I ve never used it before so there are a few things I don t understand. In my current code, I have a class similar to this: class ...

热门标签