8

我相信熟悉 HQL 的人(我自己是新手)可以轻松回答这个问题。

在我的 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 查询中,我想检索其发行日期包含在 range 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:00Fri Nov 27 22:01:20 CET 2009

我也尝试将 date1 转换为 Date 类但没有成功

那么正确的 HQL 代码是什么?我应该使用 patternForStyle 方法转换为特定格式(哪一种?)还是有另一种 -cleaner- 方法来做到这一点?

谢谢,

法比安。

4

3 回答 3

7

我不是 Grails 专家,但在 java 中,您通常会制作date1date2查询参数并将它们绑定为:

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 会将它们隐式转换为日期。

于 2009-12-04T23:10:00.037 回答
5

我通过 ChssPly 指出,您应该将date1and声明date2为查询参数(位置或命名),然后绑定它们。在这里,我们将使用命名参数。使用 Grails 传递命名查询参数的常用方法是通过 a Map

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

检查executeQuery()文档以了解这两个选项的语法详细信息。

于 2009-12-05T08:42:25.867 回答
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 作为后端对此进行了测试。请记住将日期包装为字符串。

于 2011-11-11T02:56:13.217 回答