是否可以使用Java JDBC在varchar字段中存储和检索布尔值?
时间:2020-03-06 14:19:42 来源:igfitidea点击:
一个简单的问题:我的客户遇到这样的情况:他的数据库带有varchar字段,并且相应的jdbc代码正在存储/检索布尔值。
我想布尔值false和true将被转换为" 0"和" 1",但我想对此进行确认(我无法在线找到确切的行为规范,也许取决于每个驱动程序,在这种情况下为Oracle)。
我知道我可以自己做实验,但是我想在stackoverflow.com上尝试一下!
感谢回答,
埃里克。
解决方案
不幸的是," BOOLEAN"语义是高度特定于数据库的。我猜想Oracle驱动程序将布尔值转换为VARCHAR字段的是true和false,而不是0和1,但是我们应该自己验证一下。
我同意这样的答案,即语义是高度特定于数据库的,这就是为什么我认为重要的答案是我们不应该这样做。 JDBC驱动程序中的更改或者类似更改可能导致隐式行为中断。
相反,如果使用原始JDBC,则让代码接受布尔值并将其转换为适当的字符串(" true"或者" false"是显而易见的选择),然后将此值设置为VARCHAR列。从VARCHAR列读取时,执行相反的操作,引发或者处理异常情况,即String不是所期望的布尔值之一。
它与MySQL一起使用,该表的false值为0,true值为1.
输出:
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)); } } }
感谢所有回答,
经过一些试验,我发现Oracle确实使用了0和1值将boolean值存储在varchar2列中,而JDBC代码中没有任何映射。
就是说,如果我可以提供一些背景信息,我们将解决这种情况,即事情会"偶然地"起作用。我只是想知道在此期间,该应用程序是否会崩溃。
而且,就像我说的那样,我想看看从一开始就听过Joel / Jeff播客之后stackoverflow社区的效果如何!
确实有效!