我有一个需要支持多个数据库(MySQL,Oracle,Sybase等)的hibernate模型,并且里面有一些日期逻辑。浏览各种论坛/帖子我遇到了为Hibernate创建自定义方言并注册函数的想法,每个方言都有特定于数据库的逻辑。这些工作很精彩(只显示相关的部分 - 提前道歉,我不得不混淆帖子的一些值和字段名称):
public MyOracle10gDialect() {
super();
SQLFunctionTemplate sqlFunctionTemplate =
new SQLFunctionTemplate(Hibernate.DATE, "SYSDATE - ?1");
registerFunction("date_sub_days", sqlFunctionTemplate);
}
public MyMySQLDialect() {
super();
SQLFunctionTemplate sqlFunctionTemplate =
new SQLFunctionTemplate(Hibernate.DATE, "DATE_SUB(UTC_TIMESTAMP(),INTERVAL ?1 DAY)");
registerFunction("date_sub_days", sqlFunctionTemplate);
}
现在我需要使用一个函数来解析传递给这个函数的参数。不幸的是我无法访问使用此模型的代码,否则我只是将逻辑移动到代码中,但有没有办法做嵌套函数?我想使用'GREATEST(x,y,z)'作为我的'date_sub_days'函数的参数。我基本上希望这个工作并且失败了:
WHERE date_sub_days(GREATEST(:TRADE_HISTORY_MAX_DAYS,:ORDER_HISTORY_MAX_DAYS,:NEG_HISTORY_MAX_DAYS)) < value1
因为它没有将“最大”函数解析为单个参数。
在MySQL中,我将以下内容打印到控制台:
Hibernate:
select blah from blah where
DATE_SUB(UTC_TIMESTAMP(),INTERVAL GREATEST(? DAY) < value1
ERROR util.JDBCExceptionReporter - Parameter index out of range (2 > number of parameters, which is 1).
在Oracle中,我将以下内容打印到控制台:
Hibernate:
select blah from blah where
SYSDATE - GREATEST(?<value1
ERROR util.JDBCExceptionReporter - Invalid column index
很想听听有关如何在方言或HQL中进行更改的建议。
答案 0 :(得分:0)
我找不到让嵌套函数工作的方法,但我确实提出了一个非常简单的解决方法。它缺乏我所针对的代码重用(所以必须对所有函数进行任何更改)但至少它允许我继续使用自定义方言。
而不是试图嵌套函数:
WHERE date_sub_days(GREATEST(:TRADE_HISTORY_MAX_DAYS,:ORDER_HISTORY_MAX_DAYS,:NEG_HISTORY_MAX_DAYS))
我创建了一个单独的函数,其中包含更多参数:
WHERE date_sub_days_greatest(:TRADE_HISTORY_MAX_DAYS,:ORDER_HISTORY_MAX_DAYS,:NEG_HISTORY_MAX_DAYS)
并在方言级别嵌套逻辑:
SQLFunctionTemplate dateSubDaysFunction = new SQLFunctionTemplate(Hibernate.DATE, "SYSDATE - ?1");
registerFunction("date_sub_days", dateSubDaysFunction);
SQLFunctionTemplate dateSubDaysGreatestFunction = new SQLFunctionTemplate(Hibernate.DATE, "SYSDATE - GREATEST(?1,?2,?3)");
registerFunction("date_sub_days_greatest", dateSubDaysGreatestFunction);
希望能帮助其他人!