2015-04-06 45 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可移植性,但這可能不是您的情況所關心的問題。