2015-04-06 116 views
1

中的SQL函数操纵时间戳(GMT至给定UTC)根据客户端的UTC时间(意思是客户端的时区偏移量),按月/日/小时对存储有GMT 0时间戳的存储数据进行分组应该添加到时间戳)。使用JPA

在SQL中,查询应(按天分组时)看起来像:

SELECT * 
FROM  myentity 
GROUP BY dayofweek (date_add (mytimestampcolumn, INTERVAL timezonedifference hours)) 

在JPA,下面的代码工作正常,为“星期几”是一个已知的(注册)函数JPA:

CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder(); 
Expression<Integer> timeUnitFunction = criteriaBuilder.function("dayofweek", Integer.class, from.<Date>get("timestampColumn")); 
query.groupBy(timeUnitFunction); 

它然而,不考虑时区偏移,所以我想用另一个数据库的功能和更改的第二行成类似:

criteriaBuilder.function("dayofweek", Integer.class, criteriaBuilder.function("date_add", Date.class, "hour", timezoneDifferece, from.<Date>get("timestampColumn"))) 

只有ADD_DATEADD_TIME不是我所能看到的注册JPA功能。

使用自定义方言计算简单的时区偏移看起来像是一种矫枉过正。

任何关于替代JPA注册函数的任何建议,可以操纵时间戳或任何其他方式来获得想要的结果(根据变化的时区偏移按月/日/小时进行正确分组)将非常感激。

编辑: 作为评论由尼尔,DATE_ADD,与任何其他SQL函数一起被CriteriaBuilder的函数可调用方法。

但是,我不能提供date_add所需的参数“INTERVAL expr unit”格式(使用CriteriaBuilder.literal来创建String表达式不起作用)。

问题已解决使用带字符串文字的SQL“convert_tz”函数作为时区值。

+0

你是什么意思“未注册JPA功能”? “函数”方法允许你在你的JPQL中调用任何* SQL函数 - 第一个参数是将出现在SQL中的函数。 – 2015-04-06 11:09:47

+0

@NeilStockton thx的答复,所以我如何转换期望的“ADD_DATE”SQL函数参数“(时间戳,INTERVAL timeZoneOffset小时)”,到“表达式”?因为这是参数CriteriaBuilder的函数方法期望代表SQL函数参数的类型? – Daniel 2015-04-06 11:54:41

+0

取决于你想输入的文字?或者是正确类型的字段的值? cb.function的第二个参数是一个类,你没有这样做。 – 2015-04-06 12:28:41

回答

1

您可以使用cb.function(sqlFuncName, args)方法来调用任何SQL函数。 参数是表达式,传入的数量与您的SQL函数所需的一样多。如果这些参数是文字,那么您可以使用cb.literal(value)将其转换为表达式。

也许有了这些组件,您可以生成符合您目的的东西。请注意,通过调用SQL函数,您可能会失去RDBMS可移植性,但这可能不是您的情况所关心的问题。