1

我有一个需要支持多个数据库(MySQL、Oracle、Sybase 等)的休眠模型,并且其中包含一些日期逻辑。浏览各种论坛/帖子时,我想到了为 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 更改中实现此功能的建议。

4

1 回答 1

1

我找不到让嵌套函数工作的方法,但我确实想出了一个非常简单的解决方法。它缺少我想要的代码重用(因此必须对所有功能进行任何更改),但至少它允许我继续使用自定义方言。

而不是尝试嵌套函数:

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

希望可以帮助其他人!

于 2013-07-03T10:42:53.280 回答