【问题标题】:Hibernate and date comparisons休眠和日期比较
【发布时间】:2012-06-11 14:07:42
【问题描述】:

假设我有一个截止日期和一个提醒时间跨度。如何使用 Hibernate 3.6 条件查询找到到期日期小于当前日期 + 提醒的日期?换句话说,我想找到我已显示提醒的事件。当提醒应该在几天或毫秒内发送时,提醒是一个长标记,以更容易的为准。

总而言之,我的实体如下:

java.util.Date Event.DueDate
Long Event.Type.Reminder.Before // (in days or millis)

例子

Today is 2012-06-11.
Included:
  DueDate is 2012-06-15 and Before is 30 days.
Excluded:
  DueDate is 2012-06-15 and Before is 1 day.

【问题讨论】:

    标签: database hibernate date comparison


    【解决方案1】:

    这正是 ANSI SQL 所称的日期/时间算术,特别是您正在寻找 INTERVAL 数据类型处理。不幸的是,数据库对 INTERVAL 数据类型的支持差异很大。我真的很想在 HQL 中支持这一点(可能还有标准,尽管这取决于 JPA 规范委员会的协议)。就像我说的那样,困难在于对间隔的各种(如果有的话)支持。

    目前最好的选择(通过 Hibernate 4.1)是提供一个 自定义函数 (org.hibernate.dialect.function.SQLFunction) 注册到 Dialect(搜索 google 以了解这是如何完成的)或“自定义函数注册表”(org.hibernate.cfg.Configuration#addSqlFunction)。您可能希望它以间隔呈现给特定于数据库的 date-arith 表示。

    这是一个使用 Oracle NUMTODSINTERVAL 函数的示例

    public class MySqlFunction implements SQLFunction
    {
        public Type getReturnType(Type firstArgumentType,
                                  Mapping mapping) throws QueryException
        {
            return TimestampType.INSTANCE;
        }
    
        public String render(Type firstArgumentType,
                             List arguments, 
                             SessionFactoryImplementor factory) throws QueryException
        {
            // Arguments are already interpreted into sql variants...
            final String dueDateArg = arguments.get( 0 );
            final String beforeArg = arguments.get( 1 );
    
            // Again, using the Oracle-specific NUMTODSINTERVAL
            // function and using days as the unit...
            return dueDateArg + " + numtodsinterval(" + beforeArg + ", 'day')";
        }
    
        public boolean hasArguments() { return true; }
        public boolean hasParenthesesIfNoArguments() { return false; }
    }
    

    您可以在 HQL 中使用它,例如:

    select ...
    from   Event e
    where  current_date() between e.dueDate and
           interval_date_calc( e.dueDate, e.before )
    

    其中 'interval_date_calc' 是您注册 SQLFunction 的名称。

    【讨论】:

      猜你喜欢
      • 2011-09-10
      • 2010-09-18
      • 2012-10-10
      • 2012-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多