2012-05-24 35 views
1

我想选择基于日期字段条件查询的一些记录:JPA2 /休眠查询:使用日期作为查询参数忽略了“时间”的一部分

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。日期

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

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

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

回答

4

你可以写一个UTIL,并用它来截断时间部分从日期:

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

更新

截断一部分时间,从我们从数据库中获得的价值似乎是不可能与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); 

我们在这里做什么,我们比较了来自提供的输入具有休眠功能和日历功率分别帮助最新数据库年,月,日的值。

这将做到这一点。

+0

呃......我想你不明白。我的ricerca.getDataInserimento()已经以(00:00:00)作为时间部分返回一个日期时间。 db中的记录仍然是'10:16:00'。那么比较怎样才能返回一个“找到的”结果,因为它比较了不同的日期?我需要做一个比较AVOIDING比较时间部分 –

+1

更新了解决方案。 – JMelnik

+1

它是诀窍,但.....非常棘手:)我无法相信这样一个常见的查询工作。您的答案将完美与一个JPQL替代查询;)谢谢 –

0

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

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