【问题标题】:java: retrieve keys after executeBatch() in H2java:在 H2 中的 executeBatch() 之后检索键
【发布时间】:2013-01-29 10:38:57
【问题描述】:

我正在尝试从executeBatch() 事务中检索生成的密钥,但我只获得了要添加的最后一个密钥。

这是我的代码:

        PreparedStatement ps_insert = conn.prepareStatement(insertQuery, PreparedStatement.RETURN_GENERATED_KEYS);          
        for (int i = 0 ; i < adding_dates.length ; i++){
            ps_insert.setInt(1, Integer.parseInt(consultant_id));
            ps_insert.setDate(2, adding_dates[i]);
            ps_insert.setInt(3, Integer.parseInt(room_id));
            ps_insert.addBatch();
        }
        ps_insert.executeBatch();
        ResultSet rs = ps_insert.getGeneratedKeys(); //<-- Only the last key retrieved
        conn.commit();          

我做错了什么?

编辑:抱歉没有提到我在嵌入式模式下使用 H2 (http://www.h2database.com/html/main.html) 数据库。

【问题讨论】:

  • 您使用的是哪个数据库/JDBC 驱动程序?应该是JDBC实现的问题。
  • 只是为了创建完整的图片显示请rs迭代代码
  • @partlov 你是对的。部分 JDBC 实现不支持 getGeneratedKeys() 功能:stackoverflow.com/questions/13641832/…

标签: java prepared-statement


【解决方案1】:

根据 H2 jdbc driver javadocs,这是正常行为:

返回一个包含最后生成的自动增量的结果集 此连接的密钥(如果有)。如果没有生成密钥 最后一个修改语句,则返回一个空的结果集。 返回的结果集只包含最后一行的数据。

【讨论】:

  • 它不应该被认为是正常行为,而是限制。他们应该按照 JDBC 规范来实现这个,所以他们的驱动是不完整的。
  • 从 1.4.191 版本开始支持。见:github.com/h2database/h2database/issues/156
【解决方案2】:

您必须迭代 ResultSet 以检索密钥。

  PreparedStatement ps_insert = conn.prepareStatement(insertQuery, PreparedStatement.RETURN_GENERATED_KEYS);          
    for (int i = 0 ; i < adding_dates.length ; i++){
        ps_insert.setInt(1, Integer.parseInt(consultant_id));
        ps_insert.setDate(2, adding_dates[i]);
        ps_insert.setInt(3, Integer.parseInt(room_id));
        ps_insert.addBatch();
    }
    ps_insert.executeBatch();
    ResultSet rs = ps_insert.getGeneratedKeys(); //<-- Only the last key retrieved

    if (rs.next()) {
       ResultSetMetaData rsmd = rs.getMetaData();
       int colCount = rsmd.getColumnCount();

       do {
           for (int i = 1; i <= colCount; i++) {
             String key = rs.getString(i);
             System.out.println("key " + i + "is " + key);
           }
       }
      while (rs.next();)
     } 

    conn.commit();        

【讨论】:

  • 谢谢。 getGeneratedKeys() 返回一个 ResultSet,所以迭代是必要的(这是我尝试的第一件事)。对不起,我没有在前面提到。我尝试了你的迭代,但它也没有工作。
【解决方案3】:

这是 H2 实现的限制。这是issue

现在使用不带批处理的插入/更新,或通过 select 以某种方式查询生成的键。

【讨论】:

    【解决方案4】:

    如果您在 2 个线程之间共享会话/连接,并且其中两个线程尝试同时执行语句,那么您可能会看到此类问题。

    您可能需要 (a) 使用连接池或 (b) 同步您对数据库的整个访问。

    例如选项(b)

    在您的方法前面放置一个synchronize 令牌以使其线程安全

    只是一个想法,因为我不知道你完成了执行上下文

    【讨论】:

    • 谢谢。我的实现非常简单,没有共享连接,只是一个带有嵌入文件的应用程序。
    猜你喜欢
    • 1970-01-01
    • 2015-12-27
    • 1970-01-01
    • 2014-08-26
    • 1970-01-01
    • 1970-01-01
    • 2020-02-21
    • 2015-04-03
    • 1970-01-01
    相关资源
    最近更新 更多