HQL中的日期操作

时间:2012-11-26 16:25:20

标签: hibernate date hql

我想使用HQL从表中获取过期的实体。这样的事情:

select id, name from entity_table where date_creation + 10_minutes < current_time()

我无法用HQL来做到这一点。我不想在java代码中进行额外查询,处理日期等等。这必须在HQL级别上完成。

你能帮帮我吗?

2 个答案:

答案 0 :(得分:10)

根据您的数据库,这可能非常简单。 HQL支持内置的特定于供应商的特性和功能,它还支持通过注册新函数来扩展方言,如果HQL尚不支持它们的话。

假设您正在使用SQLServer(或Sybase)。 SQLServer有一个名为“DATEADD”的函数,可以非常轻松地执行您喜欢的操作。格式为:

DATEADD (datepart, number, date)

您可以直接在HQL中使用此功能,方法是首先在您自己的Hibernate方言中注册该功能。要做到这一点,您只需要扩展您当前使用的Dialect。这是一个非常简单的过程。

首先,创建自己的方言类(用您自己的数据库供应商替换'SQLServer2008Dialect'):

public class MySQLServerDialect extends SQLServer2008Dialect {

  public MySQLServerDialect() {
    registerFunction("addminutes", new VarArgsSQLFunction(TimestampType.INSTANCE, "dateadd(minute,", ",", ")"));
  }

}

接下来,修改您的hibernate配置以使用这个新类:

<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
  "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
  "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    ...
    <property name="hibernate.dialect">com.mycompany.MySQLServerDialect</property>
    ...
</hibernate-configuration>

现在只需使用以下功能:

select x from MyEntity x where addminutes(x.creationDate, 10) < current_time()

(这假设您的实体名为MyEntity,creation_date字段映射到名为creationDate的属性)。

答案 1 :(得分:3)

HQL不支持带日期和时间的算术,因此不能在不扩展HQL的情况下使用。最简单的路径可能是注册数据库供应商的SQL方言函数进行这样的计算。其他可能性是实现并注册interceptor(覆盖的方法是onPrepareStatement),如果首选带有加号和减号的语法。

当解决方案不必完全是在HQL中时,来自JVM主机的时间足够简单,最简单的解决方案是计算过去10分钟的日期并将其作为参数。如果首选数据库时间,可以通过在单独的查询中查询,然后再减少10分钟来实现。