我正在使用 JDBC 和 HSQLDB 2.2.9。将新行插入数据库并随后保留其 id
的最有效和最准确的方法是什么? (PK 设置为自动递增)值?我需要这样做的原因可能很明显,但我会用一个例子来说明讨论:
假设有一个 Customer
具有 PersonId
的表带有 FK 约束的字段引用来自 Person
的行 table 。我要新建一个Customer
,但要做到这一点,我需要先创建一个新的 Person
并使用新的 Person.id
要设置的值 Customer.PersonId
.
我见过四种方法来解决这个问题:
Person
行设置 id
字段到 null
. HSQLDB 生成下一个 id
值自动。然后对Person
进行查询表获取 id
刚刚创建的值并使用它来创建新的 Customer
排。仅检索单个整数值似乎很昂贵。
id
Person
中的值表并在 INSERT
中使用它设置 Person.id
的语句手动值。使用相同的 id
要设置的值 Customer.PersonId
.不需要从 DB 进行后续读取。如果
id
可能会出现不一致的情况获得值,但另一个连接执行 INSERT
在我面前的 table INSERT INTO Person...
语句被执行。 INSERT
语句,如上面的选项 1,设置 id=null
允许自动生成。然后使用 getGeneratedKeys
检索在最后一条语句中生成的 key 的方法。我认为这听起来是一个不错的选择,但我无法让它发挥作用。这是我的代码片段:
// PreparedStatement prepared previously...
preparedStatement.executeUpdate();
ResultSet genKeys = preparedStatement.getGeneratedKeys();
int id;
if (genKeys.next()) {
id = genKeys.getInt(1);
}
// Finish up method...
此代码返回一个空
ResultSet
为 genKeys
.我在使用 getGeneratedKeys
方法不对?如果我能让这个工作,这可能是要走的路。 INSERT
允许自动生成的语句 id
.然后立即执行CALL IDENTITY()
检索最后一个 id
由连接生成的值(如 here 和 this SO 问题中所述)。这似乎也是一个合理的选择,即使我必须执行额外的
executeQuery
.从积极的方面来说,我实际上能够让它与以下代码一起工作:// INSERT statement executed here...
statement = connection.createStatement();
ResultSet rs = statement.executeQuery("CALL IDENTITY();");
int id;
if (rs.next()) id = rs.getInt(1);
// Finish up method...
所以,总而言之,前两个选项我并不疯狂。后两个似乎没问题,但我只能让选项 4 起作用。哪个选项是首选,为什么?如果选项 3 是最好的,我做错了什么?另外,有没有我没有提到的更好的方法?我知道像“更好”这样的词可能是主观的,但我正在使用一个简单的数据库,并且想要最直接的解决方案,该解决方案不会打开数据库以应对可能的不一致并且不会增加事务失败率(由于尝试使用已存在的
id
创建记录)。这似乎是一个基本问题(也是必不可少的),但我找不到关于最佳方法的太多指导。谢谢。
编辑:
我刚找到 this讨论我的选项 3 的问题。根据接受的答案,我似乎遗漏了
Statement.RETURN_GENERATED_KEYS
启用该功能所需的参数。我没有显示 prepareStatement
方法在我的代码片段中,但我使用的是单参数版本。我需要使用重载的两个参数版本重试。还有一些其他 SO 问题与我的问题密切相关。所以,我想我的可能被认为是重复的(不确定我之前是如何错过其他问题的)。但我仍然希望获得有关是否认为一种解决方案比其他解决方案更好的任何指导。现在,如果我让选项 3 起作用,我可能会选择它。
最佳答案
我没有足够的声誉来评论 neizan 的回答,但这是我解决同样问题的方法:
使用 HSQLDB 2.2.9 的示例:
CREATE TABLE MY_TABLE (
ID INTEGER IDENTITY,
NAME VARCHAR(30)
)
然后在Java中:
PreparedStatement result = cnx.prepareStatement(
"INSERT INTO MY_TABLE(ID, NAME) VALUES(NULL, 'TOM');",
RETURN_GENERATED_KEYS);
int updated = result.executeUpdate();
if (updated == 1) {
ResultSet generatedKeys = result.getGeneratedKeys();
if (generatedKeys.next()) {
int key = generatedKeys.getInt(1);
}
}
关于java - 如何使用 JDBC 和 HSQLDB 检索以前自动生成的 PK ID 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17858499/