【问题标题】:Oracle "boolean" to Java Boolean - how to convert automaticallyOracle "boolean" 到 Java Boolean - 如何自动转换
【发布时间】:2013-12-14 20:45:59
【问题描述】:

我正在开发一个 DB 层,使用 JDBC (ojdbc6.jar),它允许通过获取和返回包含名称/值对的 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 DB 中没有 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,在这种情况下我可以安全地调用 @ 987654326@ 并获取 Java 布尔数据类型的字段值。

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

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

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

关于这种技巧的任何想法(即使不是 100% 安全,但相当安全)?

谢谢。

编辑 举个例子,在 Oracle 中使用 RAW(1) 可以完美地解决问题,因为任何地方的任何人都将 RAW(1) 用于其他任何事情的可能性几乎为零。 RAW(1) 的问题在于它很难在 SQL 查询中使用,即很难在 WHERE 中使用这种“布尔”定义。

【问题讨论】:

  • 如果您直接使用 ResultSet,而不是使用不会增加太多价值的 Map,结果集将为您进行适当的、明确定义的转换。
  • 为什么要将 CHAR 字段设置为数值?不应该是 '0' 还是 '1',或者创建一个 number(1) 字段。
  • @JBNizet,如您所见,我在数据层中使用ResultSet。问题是我的代码应该能够自动决定何时使用rs.getBoolean() 以及何时使用rs.getString()。想象一下,然后我将检索到的数据序列化为 JSON - 我希望布尔值在我的 JSON 中显示为 true/false 而不是 "1"/"0"。问题是如何使用ResultSet 来执行此操作,如果我不知道某个特定字段是否是 bool,我只知道它的 Oracle DB 定义。
  • @nidhin,我不问 Oracle 中是否有布尔值。我知道没有。这就是为什么我正在寻找一种替代方法来将 Oracle 中可用的任何 IS 转换为 Java 布尔值。

标签: java sql database oracle jdbc


【解决方案1】:

好的,这就是它的实现方式,很好:

  • 在 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到二进制转换的奇怪处理,它总是会返回空结果。

上述问题,如果扩展到一个非常大的长寿命系统不是万无一失的,所以它不够安全。我决定采用更直​​接的方法 - 我有一个连接集标志,我在其中指定它是“我的”数据库连接(在这种情况下,我可以将 CHAR(1) 视为 Java 布尔值)还是“外部”数据库(在这种情况下不支持 Java Boolean)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-24
    • 2011-09-07
    • 1970-01-01
    相关资源
    最近更新 更多