HSQLDB 2.3 和参数绑定问题

Posted

技术标签:

【中文标题】HSQLDB 2.3 和参数绑定问题【英文标题】:HSQLDB 2.3 and issues with parameter binding 【发布时间】:2015-06-06 15:12:07 【问题描述】:

我有一个生产 Oracle 数据库,我使用 HSQLDB 2.3 作为集成测试数据库来验证一些 DAO 方法。我注意到 HSQL 不能很好地处理来自 Java 的 PreparedStatement 的日期和参数绑定。例如,下面的查询按预期工作,假设 column2 是日期类型:

select
    column1,
    column2
from
    table
where
    trunc(column2) = trunc(sysdate + 14)
    and column3 = ?

但是,当我在第一个参数 (?) 上设置 Int preparedStatement.setInt(1, 14) 时,这另一个查询根本不起作用。不用说它在 Oracle 中完美运行。

select
    column1,
    column2
from
    table
where
    trunc(column2) = trunc(sysdate + ?)
    and column3 = ?

奇怪的是,如果您尝试select (sysdate + 14) future from any_single_row_table 之类的操作,它会按预期工作,但如果您尝试select (sysdate + ?) future from any_single_row_table,它会显示当前日期

为什么会这样?它是 HSQL 准备语句实现中的错误吗?有什么解决办法吗?

【问题讨论】:

另一个很好的例子,说明使用与生产环境不同的 DBMS 进行测试是个坏主意。 在我的完美世界中,Oracle 和所有大玩家都将拥有用于测试目的的极轻量“内存”数据库,因此我们不会出现这种不匹配的情况。但不幸的是,在残酷的现实世界中情况并非如此,我们必须依靠这些次优的解决方案才能继续前进并提供优质产品。 我认为不需要用于测试的轻型内存数据库。只需设置一个运行 Oracle 的服务器并让您的单元测试连接到该服务器。它甚至可以在您的 CI 服务器上运行——如果您不对其施加沉重的负载,Oracle 实际上并不需要那么多资源。你目前的问题只是冰山一角 如果您有一个非常小的团队在处理相同的组件,那么您的解决方案很酷,否则这是一场噩梦,因为您永远无法确定 DB 状态是什么,或者如果 DDL 已更改,您也不知道.在每个开发人员工作站中安装 Oracle XE 是一种矫枉过正的做法。其实这是一个没完没了的讨论。 我说的不是在开发人员的计算机上安装一次。我说的是所有单元测试都使用的一个专用服务器。当然,您需要像 Liquibase 这样与您的构建系统集成的东西,以使数据库模型自动保持最新。 【参考方案1】:

您正在使用 Oracle 特有的简单日期算法,并且在某种程度上受 HSQLDB 支持。您可以尝试使用标准 SQL 的显式 INTERVAL 值。您还应该使用最新版本的 HSQLDB(当前为 2.3.3 候选版本),因为每个版本的语法兼容性都在发展:

select
    column1,
    column2
from
    table
where
    trunc(column2) = trunc(sysdate + cast(? as interval day))
    and column3 = ?

【讨论】:

抱歉,但我认为情况并非如此,因为如上所述,日期操作运行良好。如果我用 int 文字替换参数,它就像一个魅力。这似乎与 PreparedStatement 实现有关,但不幸的是我还没有机会确认这一点。但我会听从你的第二个建议,会给 2.3.3 一个机会(目前我使用的是 2.3.2)。 参数(它没有类型)和文字(它有一个类型)之间有一个主要区别。参数类型确定可能做错了,可以通过 CAST 强制执行。

以上是关于HSQLDB 2.3 和参数绑定问题的主要内容,如果未能解决你的问题,请参考以下文章

SpringMVC参数绑定

SpringMVC参数绑定

GIN下关于参数的多次绑定问题

细说 Web API参数绑定和模型绑定

SpringMVC参数绑定的原理

ThinkPHP学习——控制器_Action参数绑定