【问题标题】:Jdbc batched updates good key retrieval strategyjdbc批量更新好的key检索策略
【发布时间】:2024-01-24 04:31:01
【问题描述】:

我使用 JDBC 的 batchUpdate 功能将大量数据插入到带有自动生成键的表中。因为 JDBC 没有提及 batchUpdategetAutogeneratedKeys,所以我需要一些独立于数据库的解决方法。

我的想法:

  1. 在插入之前以某种方式从数据库中提取下一个分发的序列,然后手动使用密钥。但是 JDBC 没有getTheNextFutureKeys(howMany)。那么如何做到这一点呢?正在拉钥匙,例如在Oracle 中也有事务保存?因此,只有一个事务可以提取相同的一组未来密钥。

  2. 添加一个额外的列,其中包含仅在交易期间有效的虚假 id。

  3. 使用所有其他列作为辅助键来获取生成的键。这不是真正符合 3NF 的...

是否有更好的想法,或者我如何以通用的方式使用想法 1?

【问题讨论】:

    标签: database oracle jdbc auto-generate batch-updates


    【解决方案1】:

    从来没有遇到过这个,所以我潜入了一点。 首先,一种方法可以从 JDBC 语句中检索生成的 id:

    String sql = "INSERT INTO AUTHORS (LAST, FIRST, HOME) VALUES " +
                   "'PARKER', 'DOROTHY', 'USA', keyColumn";
    
    int rows = stmt.executeUpdate(sql, 
                   Statement.RETURN_GENERATED_KEYS);
    
    ResultSet rs = stmt.getGeneratedKeys();
    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();)
    } 
    else {
             System.out.println("There are no generated keys.");
    }
    

    看到这个http://download.oracle.com/javase/1.4.2/docs/guide/jdbc/getstart/statement.html#1000569

    另外,理论上可以和JDBC batchUpdate结合使用

    虽然,这种组合似乎相当重要,但请参考此线程。 我建议尝试一下,如果不成功,请退回到从序列中预取。

    【讨论】:

      【解决方案2】:

      据我所知,getAutogeneratedKeys() 也可以进行批量更新。

      它返回一个包含所有新创建的 id 的 ResultSet - 而不仅仅是一个值。

      但这需要在 INSERT 操作期间通过触发器填充 ID。

      【讨论】:

      • 其实我认为你不需要触发器来使用getAutogeneratedKeys(),如果你有这样的插入INSERT INTO FOO (ID, NAME) VALUES (FOO_SEQ.NEXTVAL, ?)
      • 正确,那么你就不需要触发器了。
      【解决方案3】:

      部分回答

      正在拉钥匙,例如在 Oracle 中还有事务保存?

      是的,从序列中获取值是事务安全的,我的意思是即使您回滚事务,数据库返回的序列值在任何情况下都不会再次返回。

      因此您可以从序列中预取 id-s 并在批量插入中使用它们。

      【讨论】:

      • 好的,谢谢,听起来不错。但是有没有 JDBC 方法来获取一堆密钥?
      • 我会使用一个存储过程,它从一个序列中返回给定数量的值。如果你不能处理这个问题,那就是另一个问题了。