微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

多个预处理语句的 JDBC 批处理

如何解决多个预处理语句的 JDBC 批处理

是否可以将来自多个 JDBC 准备好的语句的提交批处理在一起?

在我的应用程序中,用户将插入一条或多条记录以及相关表中的记录。例如,我们需要更新“contacts”表中的一条记录,删除“tags”表中的相关记录,然后插入一组新的标签

UPDATE contacts SET name=? WHERE contact_id=?;
DELETE FROM tags WHERE contact_id=?;
INSERT INTO tags (contact_id,tag) values (?,?);
// insert more tags as needed here...

这些语句需要成为单个事务的一部分,我想在到服务器的单次往返中完成它们。

要在单次往返中发送它们,有两种选择:为每个命令创建一个 Statement 然后调用 .addBatch(),或者为每个命令创建一个 PreparedStatement,然后调用 {{ 1}}、.setString() 等用于参数值,然后调用 .setInt()

第一种选择的问题在于,在 ..addBatch() 调用中发送完整的 sql 字符串效率低下,而且您无法从经过清理的参数输入中获益。

第二种选择的问题在于它可能不保留 sql 语句的顺序。例如,

addBatch()

在上面的代码中,是否可以保证所有语句都按照我们调用Connection con = ...; PreparedStatement updateState = con.prepareStatement("UPDATE contacts SET name=? WHERE contact_id=?;"); PreparedStatement deleteState = con.prepareStatement("DELETE FROM contacts WHERE contact_id=?;"); PreparedStatement insertState = con.prepareStatement("INSERT INTO tags (contact_id,?);"); updateState.setString(1,"Bob"); updateState.setInt(1,123); updateState.addBatch(); deleteState.setInt(1,123); deleteState.addBatch(); ... etc ... ... Now add more parameters to updateState,and addBatch()... ... repeat ... con.commit(); 的顺序执行,即使是在不同的准备好的语句中?排序显然很重要;我们需要在插入新标签之前删除标签

我还没有看到任何说明将为给定连接保留语句顺序的文档。

我正在使用 Postgres 和认的 Postgres JDBC 驱动程序(如果有的话)。

解决方法

批处理是每个语句对象,因此每个 executeBatch() 调用对 StatementPreparedStatement 对象执行一个批处理。换句话说,这仅执行与该语句对象的批处理关联的语句(或值集)。不可能跨多个语句对象“排序”执行。在单个批次中,订单被保留。

如果您需要按特定顺序执行语句,则需要按该顺序显式执行它们。这要么意味着对每个值集单独调用 execute(),要么使用单个 Statement 对象并即时生成语句。由于 SQL 注入的可能性,不推荐使用最后一种方法。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。