【问题标题】:Access to auto increment identity field after SQL insert in Java在 Java 中插入 SQL 后访问自动增量标识字段
【发布时间】:2010-09-09 17:28:23
【问题描述】:

关于如何通过java.sql.Statement.executeUpdate 读取分配给新创建记录的自动递增标识字段的任何建议?

我知道如何在 SQL 中为多个 DB 平台执行此操作,但想知道 java.sql 中存在哪些独立于数据库的接口来执行此操作,以及人们对跨 DB 平台的体验的任何输入。

【问题讨论】:

    标签: java sql


    【解决方案1】:
    ResultSet keys = statement.getGeneratedKeys();
    

    稍后,只需遍历 ResultSet。

    【讨论】:

    • 哇,我不知道。我从 1.2 开始一直在使用 java,我想我没有注意到这个方法是什么时候添加的。
    【解决方案2】:

    以下代码片段应该可以做到:

    PreparedStatement stmt = conn.prepareStatement(sql, 
                                     Statement.RETURN_GENERATED_KEYS);
    // ...
    
    ResultSet res = stmt.getGeneratedKeys();
    while (res.next())
        System.out.println("Generated key: " + res.getInt(1));
    

    众所周知,这适用于以下数据库

    • 德比
    • MySQL
    • SQL 服务器

    对于它不起作用的数据库(HSQLDB、Oracle、PostgreSQL 等),您需要使用特定于数据库的技巧。例如,在 PostgreSQL 上,您可以调用 SELECT NEXTVAL(...) 获取相关序列。

    注意executeUpdate(...) 的参数是类似的。

    【讨论】:

    • “res.getInt(0)”上面的答案中的轻微错字应该是“res.getInt(1)”。还不能编辑自己。总有一天:)
    • 可能是旧帖子,但你有 Dijkstra 的论文的链接,他解释了为什么 0 索引数组更好,我很久以前就看到了,但我不记得在哪里。跨度>
    【解决方案3】:

    @ScArcher2

    打第二个电话是非常危险的。 INSERTing 和选择生成的自动生成键的过程必须是原子的,否则您可能会在键选择上收到不一致的结果。考虑两个异步INSERTs,它们都在其中一个有机会选择生成的密钥之前完成。哪个进程获取哪个键列表?大多数跨数据库 ORM 必须做一些烦人的事情,比如进程内线程锁定,以保持结果的确定性。这不是您想手动完成的事情,尤其是如果您使用的数据库确实支持原子生成的密钥检索(HSQLDB 是我所知道的唯一一个不支持的数据库)。

    【讨论】:

    • 这是数据库处理的事情。它甚至可以与 HSQLDB 一起使用。它们提供了一个 IDENTITY() 函数,您可以在插入一个值后调用该函数以获取最后一个插入 ID。它在他们的文档中,并不是“非常危险”。我认为你被误导了。
    • 不幸的是,IDENTITY() 函数获取了最后一个 INSERT id,即最后一个插入的 ID。如果两个线程异步执行插入,则一个线程可能会获得另一个线程的 ID。
    【解决方案4】:

    @ScArcher2:我同意,Hibernate 需要再次调用以获取新生成的身份,除非使用高级生成器策略(序列、hilo...)

    【讨论】:

      【解决方案5】:

      我总是不得不在插入后使用查询进行第二次调用。

      你可以使用像 hibernate 这样的 ORM。我认为它会为你做这些事情。

      【讨论】:

      • 第二次调用很危险,因为它会遇到同步问题。最佳情况下,获取自动生成的密钥和实际的 INSERT 应该是原子的,可以作为一个操作,也可以作为同一事务中的两个操作(例如 PostgreSQL)。
      • 我使用过的所有数据库都支持在插入后获取 id。数据库处理同步。它基于您的连接和最后插入。因此,如果您的数据库提供了这种访问数据的方式,或者您正在使用事务,这并不危险。
      猜你喜欢
      • 1970-01-01
      • 2012-05-29
      • 1970-01-01
      • 1970-01-01
      • 2014-01-10
      • 1970-01-01
      • 1970-01-01
      • 2014-12-25
      • 1970-01-01
      相关资源
      最近更新 更多