我需要计算JPA中两个日期之间的天数。
例如:
CriteriaBuilder.construct(
MyCustomBean.class
myBean.get(MyBean_.beginDate), //Expression<Date>
myBean.get(MyBean_.endDate), //Expression<Date>
myDiffExpr(myBean) //How to write this expression from the 2 Expression<Date>?
);
到目前为止,我试过了:
1)CriteriaBuilder.diff()
。但它没有编译,因为此方法需要一些N extends Number
而Date
不会扩展Number
。
2)我试图扩展PostgreSQL82Dialect
(因为我的目标数据库是PostgreSQL):
public class MyDialect extends PostgreSQL82Dialect {
public MyDialect() {
super();
registerFunction("datediff",
//In PostgreSQL, date2 - date1 returns the number of days between them.
new SQLFunctionTemplate(StandardBasicTypes.LONG, " (?2 - ?1) "));
}
}
这个编译并且请求成功但返回的结果不一致(从今天到明天之间的78天)。
你会怎么做?
答案 0 :(得分:2)
JPA 2.1规定在JPQL语句中使用“FUNCTION(funcName,args)”。这允许这样的处理。
答案 1 :(得分:1)
看起来您正在寻找使用JPQL的解决方案来执行SELECT p FROM Period p WHERE datediff(p.to, p.from) > 10
之类的查询。
我担心JPQL中没有这样的功能所以我建议使用本机SQL。如果用Hibernate的SQLFunctionTemplate
扩展Dialect,你的想法非常聪明。我宁愿将其更改为使用DATE_PART('day', end - start)
,因为这是使用PostgreSQL实现日期之间差异的方法。
您也可以定义函数in PostgreSQL and using it with criteria function()
。
'CREATE OR REPLACE FUNCTION "datediff"(TIMESTAMP,TIMESTAMP) RETURNS integer AS \'DATE_PART('day', $1 - $2);\' LANGUAGE sql;'
cb.function("datediff", Integer.class, end, start);
答案 2 :(得分:1)
我终于发现问题来自于参数的顺序不是我预期的那个:
/*
*(?2 - ?1) is actually equivalent to (? - ?).
* Hence, when I expect it to evaluate (date2 - date1),
* it will actually be evaluated to (date1 - date2)
*/
new SQLFunctionTemplate(StandardBasicTypes.LONG, " (?2 - ?1) "));
我打开了new question以了解此行为是否是错误或功能:
答案 3 :(得分:0)
1)CriteriaBuilder.diff()。但是它没有编译,因为这个方法需要一些N扩展Number而Date不会扩展Number。
尝试在每个日期使用mili秒,如下所示。
Date date = new Date()//use your required date
long millisecond = date.getTime();//Returns no of mili seconds from 1 Jan, 1970 GMT
java中的数字长,根据自动装箱你可以使用它。可能这可以帮助。