java - JDBC getGeneratedKeys() 方法是否总是与插入元素的顺序相同
问题描述
我使用executeBatch()
JDBC 插入多行,我想为另一个插入获取插入行的 id 我为此目的使用此代码:
insertInternalStatement = dbConncetion.prepareStatement(INSERT_RECORD, generatedColumns);
for (Foo foo: foosHashSet) {
insertInternalStatement.setInt(1, foo.getMe());
insertInternalStatement.setInt(1, foo.getMe2());
// ..
insertInternalStatement.addBatch();
}
insertInternalStatement.executeBatch();
// now get inserted ids
try (ResultSet generatedKeys = insertInternalStatement.getGeneratedKeys()) {
Iterator<Foo> fooIterator= foosHashSet.iterator();
while (generatedKeys.next() && fooIterator.hasNext()) {
fooIterator.next().setId(generatedKeys.getLong(1));
}
}
它工作正常并返回 ID,我的问题是:
如果我迭代
getGeneratedKeys()
并且foosHashSet
id 会以相同的顺序返回,以便从数据库返回的每个 id 都属于相应的 Foo 实例?当我使用多线程和以上代码同时在多个线程中运行时怎么办?
有没有其他解决方案?我有两个表 foo1 和 foo2,我想先插入 foo1 记录,然后使用它们的主 id 作为 foo2 外键。
解决方案
鉴于getGeneratedKeys
JDBC 规范中未定义对批处理执行的支持,行为将取决于所使用的驱动程序。我希望任何支持生成的用于批处理执行的密钥的驱动程序都按添加到批处理中的顺序返回 ID。
但是,您使用 a 的事实Set
是有问题的。大多数集合的迭代顺序没有定义,并且可以在迭代之间改变(通常只有在修改之后,但理论上你不能假设任何关于顺序的事情)。您需要使用具有保证顺序的东西,例如 aList
或 a LinkedHashSet
。
在这里应用多线程可能是个坏主意:您一次只能使用来自单线程的 JDBC 连接。考虑多线程要么需要正确的锁定,要么需要您拆分工作负载以便它可以使用单独的连接。很难说这会改善还是恶化性能。
推荐阅读
- c# - ASP .Net MVC 简单任务
- c# - 使用 Linq 查询和 EntityFrameworkCore 2.2 返回动态字段
- python - 我可以标准化我的 PCA 应用计数向量吗?
- php - JSON 数组转换为 CSV
- javascript - 可以在控制台看到 JSON 数据,不能渲染到浏览器
- php - 带有 mysql 的 Kubernetes php Web 应用程序并存储上传的图像
- python-3.x - pandas,如何将任何包含单词的列转换为数字(即映射它们)?
- express - 为 vue 配置 webpack,使后端 express 服务器位于 ECMA2016 中
- php - 全球期权价格更新 Opencart
- r - ggplot2 - 注释外部情节