8

我想使用 HQL 从表中获取过期实体。像这样的东西:

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

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

你能帮我么?

4

2 回答 2

11

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

假设您正在使用 SQLServer(或 Sybase)。SQLServer 有一个名为“DATEADD”的函数,它可以很容易地做你喜欢的事情。格式为:

DATEADD (datepart, number, date)

您可以通过首先在您自己的 Hibernate Dialect 中注册该函数来直接在 HQL 中使用该函数。为此,您只需扩展您当前使用的方言。这是一个非常简单的过程。

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

public class MySQLServerDialect extends SQLServer2008Dialect {

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

}

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

<?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 的属性)。

于 2012-11-26T21:49:47.123 回答
3

HQL does not support arithmetic with date and time, so it is not possible without extending HQL. Easiest path is probably to register database vendors SQL dialect function for such a calculation. Other possibility is to implement and register interceptor (method to override is onPrepareStatement), if syntax with plus and minus signs is preferred.

When solution does not have to be purely in HQL and time from the JVM host is enough easiest solution is to calculate date that is 10 minutes in past and give it as an argument. If database time is preferred, that can be achieved by querying it in separate query and then decrementing 10 minutes from it.

于 2012-11-26T20:25:21.423 回答