【问题标题】:Workaround for "null primitives" in JDBC PreparedStatement? [duplicate]JDBC PreparedStatement 中“空原语”的解决方法? [复制]
【发布时间】:2013-07-13 11:36:39
【问题描述】:

当使用原始 JDBC 时,您可以像这样参数化 PreparedStatement

PreparedStatement statement = connection.prepareStatement(someSQLString);
String someString = getSomeString();
Integer int = getSomeInteger();
statement.setString(1, someString);
statement.setLong(2, 5L);
statement.setInt(3, int);

...

在这里,如果 someStringnull,那很好 - 字符串可以为空。但是如果getSomeInteger()返回null,我们就有问题了。

PreparedStatement#setInt(int,int) 将原始int 设置为值,因此不能为null

但是,对于这条特定记录,我可能希望上面第 3 列的值是 null 毕竟,我曾经使用过的每个 RDBMS 都允许数字 ( INT、LONG 等)字段为 NULLABLE...

那么解决方法是什么?

【问题讨论】:

    标签: java sql jdbc prepared-statement nullable


    【解决方案1】:

    不要使用其中任何一个,而是使用 setObject,让 JDBC 驱动程序代替您管理 null 值。

    【讨论】:

    • 谢谢@Luiggi Mendoza (+1) - 你能确认setObject 处理所有类型,并在任何类型为NULL 时处理?基本上,它涵盖了所有场景吗?有什么需要注意的警告或陷阱吗?再次感谢!
    • @IAmYourFaja 这将取决于 JDBC 驱动程序。请注意setObject 文档的最后一部分:注意: 并非所有数据库都允许将非类型 Null 发送到后端。为了获得最大的可移植性,应该使用 setNull 或 setObject(int parameterIndex, Object x, int sqlType) 方法来代替 setObject(int parameterIndex, Object x)。我建议做一些测试,然后根据你的情况使用最好的方法。
    • 好的 - 再次感谢@Luiggi Mendoza (+1) - 最后一次跟进:setObject(int,Object,int) 会涵盖所有类型,null 和 non-null 之类的吗?听起来这就是我想要的……换句话说:我是否保证此方法正确处理所有/大多数 JDBC 驱动程序中的所有类型和空值?
    • @IAmYourFaja 再次,这取决于 JDBC 驱动程序。做一些测试(因为你从来没有说明你使用哪个 JDBC 驱动程序)然后决定你应该使用 setObject 还是 setNull
    • 如果setObject 更合适我不明白为什么我们让setTYPE 方法在PreparedStatement 中。我们是否应该期望它们在不久的将来被弃用?
    【解决方案2】:

    您可以使用PreparedStatement 类的setNull(int parameterIndex, int sqlType) 方法。

    这是一个如何使用它的示例:

      String query = 
         "insert into nullable_table(id,string_column, int_column) values(?, ?, ?)";
    
      // create PrepareStatement object
      PreparedStatement pstmt = connection.prepareStatement(query);
      pstmt.setString(1, id);
      pstmt.setNull(2, java.sql.Types.VARCHAR);
      pstmt.setNull(3, java.sql.Types.INTEGER);
    

    示例取自here

    【讨论】:

    • 谢谢@kocko (+1) - 请在 Luiggi 的回答下阅读我的问题 - 我有同样的问题要问你!再次感谢!
    • 谢谢!我在谷歌上搜索了 15 分钟,你的帖子是最清晰、最简洁的!
    • 什么是 long 的正确 SQL 类型?
    【解决方案3】:

    您需要使用setNull() 方法。基于参数是null 或不检查您需要调用setNull()(或)setInt()

    【讨论】:

    • 谢谢@Nambari (+1) - 请在 Luiggi 的回答下阅读我的问题 - 我有同样的问题要问你!再次感谢!
    • @IAmYourFaja:正如 Luggin 评论的那样,如果您使用 setObject,您将坚持使用数据库驱动程序实现,如果其他不支持您最终将更改您的代码。如果我必须决定,我不会使用 setObject() 方法(假设我们不知道我们将使用哪些数据库)。我很乐意添加几行代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-12
    • 1970-01-01
    • 1970-01-01
    • 2021-12-18
    • 2013-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多