【发布时间】:2010-09-09 17:28:23
【问题描述】:
关于如何通过java.sql.Statement.executeUpdate 读取分配给新创建记录的自动递增标识字段的任何建议?
我知道如何在 SQL 中为多个 DB 平台执行此操作,但想知道 java.sql 中存在哪些独立于数据库的接口来执行此操作,以及人们对跨 DB 平台的体验的任何输入。
【问题讨论】:
关于如何通过java.sql.Statement.executeUpdate 读取分配给新创建记录的自动递增标识字段的任何建议?
我知道如何在 SQL 中为多个 DB 平台执行此操作,但想知道 java.sql 中存在哪些独立于数据库的接口来执行此操作,以及人们对跨 DB 平台的体验的任何输入。
【问题讨论】:
ResultSet keys = statement.getGeneratedKeys();
稍后,只需遍历 ResultSet。
【讨论】:
以下代码片段应该可以做到:
PreparedStatement stmt = conn.prepareStatement(sql,
Statement.RETURN_GENERATED_KEYS);
// ...
ResultSet res = stmt.getGeneratedKeys();
while (res.next())
System.out.println("Generated key: " + res.getInt(1));
众所周知,这适用于以下数据库
对于它不起作用的数据库(HSQLDB、Oracle、PostgreSQL 等),您需要使用特定于数据库的技巧。例如,在 PostgreSQL 上,您可以调用 SELECT NEXTVAL(...) 获取相关序列。
注意executeUpdate(...) 的参数是类似的。
【讨论】:
@ScArcher2
打第二个电话是非常危险的。 INSERTing 和选择生成的自动生成键的过程必须是原子的,否则您可能会在键选择上收到不一致的结果。考虑两个异步INSERTs,它们都在其中一个有机会选择生成的密钥之前完成。哪个进程获取哪个键列表?大多数跨数据库 ORM 必须做一些烦人的事情,比如进程内线程锁定,以保持结果的确定性。这不是您想手动完成的事情,尤其是如果您使用的数据库确实支持原子生成的密钥检索(HSQLDB 是我所知道的唯一一个不支持的数据库)。
【讨论】:
@ScArcher2:我同意,Hibernate 需要再次调用以获取新生成的身份,除非使用高级生成器策略(序列、hilo...)
【讨论】:
我总是不得不在插入后使用查询进行第二次调用。
你可以使用像 hibernate 这样的 ORM。我认为它会为你做这些事情。
【讨论】: