【发布时间】:2018-11-20 23:04:06
【问题描述】:
我有一个连接到 Oracle 数据库的 Java 应用程序。其中一个表包含一个 blob 列,我们使用 utl_raw.cast_to_raw 填充它,如下所示:
public class MyDAO extends JdbcDaoSupport {
public void persist(String name, String data) {
String sql = "insert into table (id, name, data) values " +
"(sequence.nextval, ?, utl_raw.cast_to_raw(?))";
getJdbcTemplate().update(sql, [name, data]);
}
}
由于某些我不知道的原因,我们在这个应用程序中没有使用 Hibernate、JPA 或类似的东西。只需简单的 SQL 语句和 Spring JDBC 即可执行它们。 (...) 无论如何,上述方法工作正常。至少对于 Oracle。
我已经建立了一个包含最少数据的内存 H2 数据库,用于我们的 JUnit 测试。但是 H2 中没有 utl_raw 包。 Apparently, the way to go is 改为使用 rawtohex function。它有点工作...但是它使数据长度加倍。例如,如果我将字符串 "TEST" 持久保存在 blob 列中,然后我检索它的值,它将变为 " T E S T"。作为一个字节数组,它将是[0, 84, 0, 69, 0, 83, 0, 84]。 H2 文档指出这是应该发生的:
将字符串转换为十六进制表示。每个字符串字符使用 4 个十六进制字符。
Weird。我想这是支持 UTF-16 字符串(?)的方式,但我使用的是 UTF-8。它实际上损坏了我的数据。
还有其他方法可以将 blob 存储在 H2 中吗?我见过 this answer where they suggest using a PreparedStatement,但是我必须自己处理连接:
super.getConnection().prepareStatement(/* ... */).executeUpdate();
// release the statement and the connection, handle exceptions
当然,它并没有太多比我们现在拥有的丑,但是,我仍然非常不愿意更改工作生产代码以使其与我们的 JUnit 测试设置兼容。
另一种选择是将 blob 当作 UTF-16 字符串来检索,因此它实际上每个字符使用 4 个十六进制。但同样,我会只为 H2 解决问题,而为 Oracle 解决问题。
我还有其他选择吗?有什么办法可以告诉 H2 数据库在rawtohex 中每个字符只使用 1 个字节?或者我可以用another function 代替rawtohex?
【问题讨论】: