【问题标题】:JPA2 / Hibernate query: using Date as a query param ignoring the "time" partJPA2 / Hibernate查询:使用日期作为查询参数忽略“时间”部分
【发布时间】:2012-05-24 08:24:38
【问题描述】:

我想根据日期字段选择条件查询的一些记录:

CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();
CriteriaQuery cq = cb.createQuery();
Root<Macchinario> from = cq.from(Macchinario.class);
cq.select(from);

cq.where(
                    cb.and(
                        cb.like(from.<String>get("marca"), "%"+ricerca.getMarca()+"%"),
                        cb.like(from.<String>get("modello"), "%"+ricerca.getModello()+"%"),
                        cb.like(from.<String>get("matricola"), "%"+ricerca.getMatricola()+"%"),

                        cb.equal(from.get("dataInserimento"), ricerca.getDataInserimento())
                    )
                );

dataInserimento 是一个 java.util.Date

我正在寻找的“Macchinario”在数据库中有“2012-05-23 10:16:00”。

ricerca.getDataInserimento() 返回“2012-05-23 00:00:00”。

如何传递该参数,告诉 jpa 忽略日期的“时间部分”?

【问题讨论】:

    标签: hibernate date jpa criteria


    【解决方案1】:

    您可以编写一个实用程序并使用它来截断日期中的时间部分:

    DateHelper.java

    public static Date getDateWithoutTime(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }
    

    然后改变

    cb.equal(from.get("dataInserimento"), ricerca.getDataInserimento())
    

    cb.equal(from.get("dataInserimento"), 
             DateHelper.getDateWithoutTime(ricerca.getDataInserimento()))
    

    更新

    从我们从 db 获得的值中截断时间部分似乎不可能使用 JPA 或 Hibernate 提供的开箱即用功能。不过,Hibernate 提供了从日期列中提取年、月和日值的功能,我们将使用它。

    Calendar dateCalendar = Calendar.getInstance();
    dateCalendar.setTime(ricerca.getDataInserimento());
    
    Path<Date> dataInserimento = from.get("dataInserimento");
    Predicate timelessPredicate = cb.and(
            cb.equal(cb.function("year", Integer.class, dataInserimento), dateCalendar.get(Calendar.YEAR)),
            cb.equal(cb.function("month", Integer.class, dataInserimento), dateCalendar.get(Calendar.MONTH) + 1),
            cb.equal(cb.function("day", Integer.class, dataInserimento), dateCalendar.get(Calendar.DATE)));
    
    cq.where(..., timelessPredicate);
    

    我们在这里所做的是,我们借助休眠功能和日历功能分别将数据库中的年、月和日值与提供的输入日期进行比较。

    这样就可以了。

    【讨论】:

    • 呃……我想你不明白。我的ricerca.getDataInserimento() 已经返回了一个以 (00:00:00) 作为时间部分的日期时间。数据库中的记录仍然有'10:16:00'。那么,当比较不同的日期时,比较如何返回“找到”结果呢?我需要做一个比较避免比较时间部分
    • 它成功了,但是.....非常棘手:) 我不敢相信所有这些都适用于这样一个常见的查询。 JPQL 替代查询将是您的完美答案;)谢谢
    • 想一想..你可以用 where date >= selectedDate 和 date
    【解决方案2】:

    您可以尝试使用适当的模式格式化日期以忽略时间部分。

    public String getDate(java.util.Date date){
    
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(date);
    }
    

    现在,您可以将日期作为正确格式的字符串,然后比较它们是否相等。

    cb.equal(getDate(from.<java.util.Date>get("dataInserimento")), getDate(ricerca.getDataInserimento()))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-09-21
      • 2013-10-22
      • 2010-11-02
      • 2014-11-01
      • 2022-10-07
      • 1970-01-01
      • 2015-05-13
      • 1970-01-01
      相关资源
      最近更新 更多