hibernate HQL中的日期操作

emeijp43  于 2023-01-21  发布在  其他
关注(0)|答案(3)|浏览(256)

我想使用HQL从表中获取过期的实体。类似于:

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

我不知道如何用HQL来做这件事。我不想做额外的查询,在java代码中处理日期等等。这必须在HQL级别上完成。
你能帮帮我吗?

4ktjp1zp

4ktjp1zp1#

根据您的数据库,这可能非常简单。HQL支持内置的特定于供应商的特性和函数,如果HQL还不支持新函数,它还支持通过注册新函数来扩展方言的能力。
假设您正在使用SQLServer(或Sybase)。SQLServer有一个名为“DATEADD”的函数,可以非常轻松地执行任何操作。格式为:

DATEADD (datepart, number, date)

你可以直接在HQL中使用这个函数,首先在你自己的Hibernate Dialect中注册这个函数。要做到这一点,你只需要扩展你当前使用的Dialect。这是一个非常简单的过程。
首先,创建您自己的方言类(将“SQLServer2008Dialect”替换为您自己的DB供应商):

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

(This假设您的实体名为MyEntity,并且creation_date字段Map到名为creationDate的属性)。

yx2lnoni

yx2lnoni2#

HQL不支持日期和时间的算术运算,因此不扩展HQL是不可能的。最简单的方法可能是注册数据库供应商的SQL方言函数以进行此类计算。如果首选带加号和减号的语法,则还可以实现并注册interceptor(要覆盖的方法是onPrepareStatement)。
当解决方案不必纯粹使用HQL并且JVM主机的时间足够时,最简单的解决方案是计算过去10分钟的日期,并给予其作为参数。如果首选数据库时间,则可以通过在单独的查询中查询它,然后从它减去10分钟来实现。

zrfyljdw

zrfyljdw3#

这个问题的其他答案是正确的w.r.t. Hibernate 5和更早的版本,但是由于人们链接到这个问题,我应该注意到他们不再是正确的w.r.t. Hibernate 6。
在H6中,查询可以用HQL写成:

select id, name from Entity where date_creation + 10 minute < current_timestamp

相关问题