Oracle "boolean" to Java Boolean - 如何自动转换



我正在使用JDBC(ojdbc6.jar)开发一个DB层,JDBC允许通过获取和返回包含名称/值对的Map来执行基本的DB操作。例如:

map.put("StrField", "str");
map.put("IntField", 10);
map.put("BoolField", true);
DB.insert(tableName, map);
...
map = DB.query("SELECT * from MY_TABLE.."); // assuming this returns only one row
Boolean flag = map.get("BoolField");
// etc...

插入操作很容易实现,因为从Java基元类型到Oracle类型的转换既简单又直观。

对于相反的方向(Oracle->Java),更正稍微复杂一些。我成功地转换了除"布尔"之外的所有类型。由于Oracle数据库中没有BOOLEAN数据类型,我正在寻找一种定义字段的方法,以便我的检索层能够清楚地将此类字段标识为BOOLEAN。

到目前为止,我发现最好的方法是使用这样的东西:

BOOL_FIELD CHAR(1) DEFAULT 0 NOT NULL CHECK (BOOL_FIELD in (0, 1))

此外,我确保在数据库中的任何地方都不使用CHAR(1),除非需要"布尔"。这并不是一个很大的限制,因为CHAR(1)对其他任何事情都不太有用。

在我的Java转换代码中,我检查特定返回的字段是否为java.sql.Types.CHAR(通过ResultSetMetaData.getColumnType()调用),还检查字段的大小是否为1,在这种情况下,我可以安全地调用ResultSet.getBoolean(),并将字段值获取为Java布尔数据类型。

到目前为止,它运行得很好,但现在我遇到了外部数据库的问题,即数据库,在其中我无法控制表/列的定义。对于这样的数据库,我可以完全不使用布尔值,但我想知道如何将我的"布尔"与其他人在外部数据库中使用的常规CHAR(1)区分开来。

我可以完全忽略这一点,在CHAR(1)的情况下,可以得到布尔值true/false,但这不是我的意图。例如,如果一个特定的CHAR(1)列的值为"X"(对于我的数据库来说不可能,但在外部数据库中大小写有效),那么我的转换代码将返回true而不是"X"。

我正在寻找一些"元数据"或技巧,我可以将其添加到我的"BOOLEAN"DB字段中,这样我的JDBC层就可以获得这些元数据,如果它得到了,假设它是我的布尔值,而不是其他人的CHAR(1),看起来很相似。

对这样的把戏有什么想法吗(即使不是100%安全,但相当安全)?

谢谢。

编辑举个例子,在Oracle中使用RAW(1)可以完美地实现这一点,因为任何人、任何地方都有可能将RAW(2)用于其他任何事情。RAW(1)的问题是它很难在SQL查询中使用,也就是说,很难用这样的"布尔"定义来进行WHERE。

好吧,下面是如何做到的,有点不错:

  • 将Oracle中的"布尔"字段定义为RAW(1):

    BOOL_FIELD RAW(1) DEFAULT '00' CHECK (BOOL_FIELD in ('00', '01'))

    任何人将RAW(1)用于任何其他的可能性几乎为零

  • 在Java中使用getString/setString将true/false转换为"00"/"01"

上述方法的主要问题是SQL语句中必须始终使用"00"/"01"。换句话说,如果有人不小心使用了WHERE BOOL_FIELD = '1',它总是会返回空结果,这是由于Oracle对字符到二进制转换的奇怪处理。

上述问题,如果扩展到一个真正大的长寿系统,是不愚蠢的,所以它不够安全。我决定采取一种更直接的方法——我有一个连接集标志,在这里我指定它是"我的"数据库连接(在这种情况下,我可以将CHAR(1)视为Java布尔)还是"外部"数据库(在这种情况下,不支持Java布尔)。

最新更新