Java中SQL插入后自动增量标识字段的访问

Java中SQL插入后自动增量标识字段的访问,java,sql,Java,Sql,关于如何通过调用java.sql.Statement.executeUpdate读取分配给新创建记录的自动递增标识字段,有什么建议吗 我知道如何在SQL中为多个DB平台执行此操作,但我想知道java.SQL中存在哪些与数据库无关的接口来执行此操作,以及人们在DB平台上使用此操作的经验的任何输入。插入后,我总是必须使用query进行第二次调用 您可以使用类似hibernate的ORM。我认为它为您提供了这些功能。以下几段代码应该可以: PreparedStatement stmt = conn.p

关于如何通过调用
java.sql.Statement.executeUpdate
读取分配给新创建记录的自动递增标识字段,有什么建议吗


我知道如何在SQL中为多个DB平台执行此操作,但我想知道java.SQL中存在哪些与数据库无关的接口来执行此操作,以及人们在DB平台上使用此操作的经验的任何输入。

插入后,我总是必须使用query进行第二次调用


您可以使用类似hibernate的ORM。我认为它为您提供了这些功能。

以下几段代码应该可以:

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 Server
对于不起作用的数据库(HSQLDB、Oracle、PostgreSQL等),您需要使用特定于数据库的技巧。例如,在PostgreSQL上,您可以调用
SELECT NEXTVAL(…)
,以获取相关序列


请注意,
executeUpdate(…)
的参数是类似的。

@ScArcher2:我同意,除非使用高级生成器策略(序列、hilo…),否则Hibernate需要进行第二次调用以获取新生成的标识

稍后,只需在ResultSet上迭代即可。

@ScArcher2


再打一次电话是非常危险的。
INSERT
ing和选择生成的自动生成键的过程必须是原子的,否则您可能会在键选择上收到不一致的结果。考虑两个异步<代码> INSERT //COS> S,它们在两个都有机会选择生成的密钥之前完成。哪个进程获取哪个密钥列表?为了保持结果的确定性,大多数跨数据库的orm必须做一些恼人的事情,比如进程内线程锁定。这不是您想手工完成的事情,特别是如果您使用的数据库确实支持原子生成密钥检索(据我所知,HSQLDB是唯一一个不支持原子生成密钥检索的数据库)。

第二次调用是危险的,因为它会遇到同步问题。最佳情况下,获取自动生成的密钥和实际插入应该是原子的,可以作为一个操作,也可以作为同一事务中的两个操作(例如PostgreSQL)。我使用过的所有数据库都支持在插入后获取id。数据库处理同步。它基于您的连接和最后一次插入。所以,如果你的数据库提供了访问数据的方法,或者你正在使用一个事务,那就不危险了。哇,我不知道。我从1.2开始使用java,我想我没有注意到这个方法是什么时候添加的,这是数据库处理的。它甚至可以与HSQLDB一起工作。它们提供了一个IDENTITY()函数,您可以在插入一个值后调用该函数以获取最后一个插入id。它在它们的文档中,并且不是“极其危险的”。我认为你的信息是错误的。不幸的是,IDENTITY()函数得到了最后一个INSERT id,也就是最后一个被插入的id。如果两个线程异步执行插入,则一个线程可能会获取另一个线程的ID。上面“res.getInt(0)”的答案中的轻微输入错误应为“res.getInt(1)”。还不能编辑我自己。有一天:)可能是老帖子,但你有没有Dijkstra的论文的链接,他在那里解释了为什么0索引数组更好,我很久以前就看到了,但我不记得在哪里。
ResultSet keys = statement.getGeneratedKeys();