3

快速提问:我的客户有这样一种情况,他的数据库带有 varchar 字段,并且相应的 jdbc 代码正在存储/检索布尔值。

我猜布尔值 false 和 true 将被转换为“0”和“1”,但我想对此进行确认(我在网上找不到精确的行为规范,可能取决于每个驱动程序, 在这种情况下是 Oracle)。

我知道我可以自己进行实验,但我想在 stackoverflow.com 上尝试一下!

感谢您的回答,

埃里克。

4

5 回答 5

2

我同意语义高度特定于数据库的答案,这就是为什么我认为重要的答案是你不应该这样做。JDBC 驱动程序或类似的更改可能会导致隐式行为中断。

相反,如果使用原始 JDBC,让代码获取布尔值并将其转换为适当的字符串('true' 或 'false' 是显而易见的选择),然后将此值设置为 VARCHAR 列。在从 VARCHAR 列读取时,执行相反的操作,抛出或处理 String 不是预期的布尔值之一的异常情况。

于 2008-09-18T02:31:53.133 回答
1

感谢您的所有回答,

经过一些实验,我看到 Oracle 确实使用值 0 和 1 将boolean值存储在varchar2列中,而 JDBC 代码中没有任何映射。

也就是说,如果我能提供一些背景信息,我们将解决这种情况,即事情会“偶然”发生。我只是想知道,与此同时,应用程序是否会崩溃。

而且,正如我所说,我想看看 stackoverflow 社区从一开始就收听了 Joel/Jeff 播客后的效果!

确实有效!

于 2008-09-18T03:38:36.330 回答
1

它适用于 MySQL,该表为 false 和 1 为 true。

输出:

123 => true
456 => false

源代码:

package com.lurz.jdbc;
import java.sql.*;
// Test using Varchar for Boolean
public class BoolTest {
   public static void main(String[] args) throws ClassNotFoundException, SQLException {
      Class.forName("com.mysql.jdbc.Driver");
      Connection conn = DriverManager.getConnection("jdbc:mysql://localhost/booltest", "booltest", "booltest");
      conn.prepareStatement("create table booltest (id bigint, truefalse varchar(10));").execute();
      PreparedStatement stmt = conn.prepareStatement("insert into booltest (id, truefalse) values (?, ?);");
      stmt.setLong(1, (long)123);
      stmt.setBoolean(2, true);
      stmt.execute();
      stmt.setLong(1, (long)456);
      stmt.setBoolean(2, false);
      stmt.execute();
      ResultSet rs = conn.createStatement().executeQuery("select id, truefalse from booltest");
      while (rs.next()) {
         System.out.println(rs.getLong(1)+ " => " + rs.getBoolean(2));
      }  
   }
}
于 2008-09-18T02:39:34.660 回答
0

不幸的是,BOOLEAN语义是高度特定于数据库的。我猜测Oracle 驱动程序会将布尔值转换为VARCHAR字段为 " true" 和 " false",而不是0and 1,但您应该自己验证这一点。

于 2008-09-18T02:13:27.063 回答
0

可以使用 VARCHAR(2) 在 Oracle 中表示 Java 布尔值。但是,我建议不要这样做,并建议您改用 NUMBER(1)。如果布尔列上有一个索引并且您在 WHERE 子句中使用它,Oracle 将对其应用 to_number 数字函数以将“0”转换为 0 或将“1”转换为 1。该函数的应用会否定使用该列上的索引,将导致您进行全表扫描。

于 2012-09-17T20:26:50.437 回答