【问题标题】:How to compare dates in hibernate如何在休眠中比较日期
【发布时间】:2012-04-09 13:26:09
【问题描述】:

在我的数据库日期为2012-04-09 04:02:532012-04-09 04:04:512012-04-08 04:04:51 等,我需要在日期字段中检索具有当前日期的数据。我的意思是我只需要匹配 2012-04-09' 。我如何使用休眠条件来做到这一点。

【问题讨论】:

    标签: java spring hibernate


    【解决方案1】:

    使用Restrictions.between() 生成日期列在'2012-04-09 00:00:00'和'2012-04-09 23:59:59'之间的where子句

    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date fromDate = df.parse("2012-04-09 00:00:00");
    Date toDate = df.parse("2012-04-09 23:59:59");
    
    criteria.add(Restrictions.between("dateField", fromDate, toDate));
    

    请注意,Criteria API 中使用的所有属性都是 Java 属性名,而不是实际的列名。


    更新:仅使用 JDK 获取当前日期的 fromDate 和 toDate

    Calendar calendar = Calendar.getInstance();
    calendar.set(Calendar.HOUR_OF_DAY, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.SECOND, 0);
    Date fromDate = calendar.getTime();
    
    calendar.set(Calendar.HOUR_OF_DAY, 23);
    calendar.set(Calendar.MINUTE, 59);
    calendar.set(Calendar.SECOND, 59);
    Date toDate = calendar.getTime();
    
    criteria.add(Restrictions.between("dateField", fromDate, toDate));
    

    【讨论】:

    • 如何从Currentdate获取fromDate和toDate
    • @Ken Chan 非常感谢您发布单个日期的日期比较。我会在解析方法中为23:59:59 +1。
    • 这很有帮助。我认为hibernate应该提供一个功能来比较没有时间的日期。
    • 虽然这适用于所有实际目的。 23:59:59 仍然不完全是 EOD。我会让java帮我解决这个问题:LocalDate.now().atTime(LocalTime.MAX).atZone(ZoneId.systemDefault()).toInstant()
    【解决方案2】:

    像这样?

    criteria.add(Expression.eq("yourDate", aDate))
    

    【讨论】:

    • 如何使用 Expression.between("yourDate", aDate, aDate+1)
    • 这对我不起作用,我认为它确实做了很多,比较日期的最佳情况是第一个答案。
    【解决方案3】:
    fromDate.setTime(new Date());
    fromDate.set(Calendar.HOUR_OF_DAY, 0);
    fromDate.set(Calendar.MINUTE, 0);
    fromDate.set(Calendar.SECOND, 0);
    fromDate.set(Calendar.MILLISECOND, 0);
    

    这段代码非常危险......如果当天切换到夏令时(例如 06.04.1980),您最终会出现以下异常!!!

     java.lang.IllegalArgumentException: HOUR_OF_DAY: 0 -> 1day
    
    
    HQL: from human pat where year(pat.birthdate) = :start_day and month(pat.birthdate) = :start_month and year(pat.birthdate) = :start_year ");
    
    params.put("start_day", startDate.get(Calendar.DAY_OF_MONTH));
    params.put("start_month", startDate.get(Calendar.MONTH) + 1);
    params.put("start_year", startDate.get(Calendar.YEAR));
    

    年/月/日函数使用底层 db 函数(提取、...)并仅比较这些值。因此,我不需要将导致上述异常的时间设置为 0。 只是我如何解决问题的一个例子!也许有帮助

    【讨论】:

      【解决方案4】:

      如何在 Hibernate 中进行操作已经说过。您可以使用例如以下方法在 Java 代码中准备 Timestamp 对象:

      Calendar cFrom = Calendar.getInstance();
      cFrom.setTime(new Date()); /* today */
      cFrom.set(Calendar.HOUR_OF_DAY, 0);
      cFrom.set(Calendar.MINUTE, 0);
      cFrom.set(Calendar.SECOND, 0);
      cFrom.set(Calendar.MILLISECOND, 0);
      Timestamp from = new Timestamp(cFrom.getTime().getTime());
      Calendar cTo = Calendar.getInstance();
      cTo.setTime(new Date()); /* today */
      cTo.set(Calendar.HOUR_OF_DAY, 23);
      cTo.set(Calendar.MINUTE, 59);
      cTo.set(Calendar.SECOND, 59);
      cTo.set(Calendar.MILLISECOND, 999);
      Timestamp to = new Timestamp(cTo.getTime().getTime());
      
      final String QUERY = ""
        + "SELECT tr "
        + "FROM Type tr "
        + "WHERE tr.timestamp >= :timestampFrom AND tr.timestamp <= :timestampTo";
      Query query = entityManager.createQuery(QUERY);
      query.setParameter("timestampFrom", from);
      query.setParameter("timestampTo", to);
      @SuppressWarnings("unchecked")
      List<Type> ts = (List<Type>)query.getResultList();
      

      【讨论】:

        【解决方案5】:

        最简单的方法是获取日期在给定日期的开始和结束之间的所有记录:

        WHERE date BETWEEN :from AND :to
        

        并在您的 Java 代码中计算 fromto

        用于计算午夜:

        import static org.apache.commons.lang.time.DateUtils.ceiling;
        import static org.apache.commons.lang.time.DateUtils.truncate;
        
        Date someDay = new Date();
        Date from = truncate(someDay, Calendar.DAY_OF_MONTH);
        Date to = new Date(ceiling(someDay, Calendar.DAY_OF_MONTH).getTime() - 1);
        

        【讨论】:

        • 我明白了。天花板和截断是为了?
        • @Romi:您需要以某种方式计算一天的开始 (Mon Apr 09 00:00:00 CEST 2012) 和结束 (Mon Apr 09 23:59:59 CEST 2012)。
        • @Romi:是的,截断返回给定一天的开始(00:00)和上限 - 第二天的开始。
        【解决方案6】:
        Restrictions.between("dateColumn", midnight1, midnight2)
        

        【讨论】:

          【解决方案7】:
          The following code will work
          
          Calendar fromDate = Calendar.getInstance();
          fromDate.setTime(new Date());
          fromDate.set(Calendar.HOUR_OF_DAY, 0);
          fromDate.set(Calendar.MINUTE, 0);
          fromDate.set(Calendar.SECOND, 0);
          fromDate.set(Calendar.MILLISECOND, 0);
          
          Calendar toDate = Calendar.getInstance();
          toDate.setTime(new Date());
          toDate.set(Calendar.HOUR_OF_DAY, 23);
          toDate.set(Calendar.MINUTE, 59);
          toDate.set(Calendar.SECOND, 59);
          toDate.set(Calendar.MILLISECOND, 999);
          
          criteria.add(Restrictions.between("loadDate", fromDate.getTime(),
                              toDate.getTime()));
          

          【讨论】:

            【解决方案8】:

            //日期时间比较 Hibernate 4.3

                 Select c from Customer c where c.date<{d '2000-01-01'}
            

            【讨论】:

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