gpt4 book ai didi

java - 多次重用 PreparedStatement

转载 作者:IT老高 更新时间:2023-10-28 11:30:09 27 4
gpt4 key购买 nike

在将 PreparedStatement 与没有任何池的单个公共(public)连接一起使用的情况下,我可以为每个 dml/sql 操作重新创建一个实例,以保持预准备语句的功能吗?

我的意思是:

for (int i=0; i<1000; i++) {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setObject(1, someValue);
preparedStatement.executeQuery();
preparedStatement.close();
}

代替:

PreparedStatement preparedStatement = connection.prepareStatement(sql);
for (int i=0; i<1000; i++) {
preparedStatement.clearParameters();
preparedStatement.setObject(1, someValue);
preparedStatement.executeQuery();
}
preparedStatement.close();

我的问题是我想把这段代码放到多线程环境中,你能给我一些建议吗?谢谢

最佳答案

第二种方法效率更高,但更好的方法是批量执行它们:

public void executeBatch(List<Entity> entities) throws SQLException { 
try (
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement(SQL);
) {
for (Entity entity : entities) {
statement.setObject(1, entity.getSomeProperty());
// ...

statement.addBatch();
}

statement.executeBatch();
}
}

但是,您一次可以执行多少个批处理取决于 JDBC 驱动程序的实现。例如,您可能希望每 1000 个批处理执行一次:

public void executeBatch(List<Entity> entities) throws SQLException { 
try (
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement(SQL);
) {
int i = 0;

for (Entity entity : entities) {
statement.setObject(1, entity.getSomeProperty());
// ...

statement.addBatch();
i++;

if (i % 1000 == 0 || i == entities.size()) {
statement.executeBatch(); // Execute every 1000 items.
}
}
}
}

对于多线程环境,如果按照正常的JDBC习语,在同一方法 block 内尽可能短的范围内获取和关闭连接和语句,则无需担心使用 try-with-resources声明如上面的片段所示。

如果这些批处理是事务性的,那么您希望关闭连接的自动提交,并且仅在所有批处理完成后才提交事务。否则可能会导致前一批批成功后一批批不成功,导致数据库脏。

public void executeBatch(List<Entity> entities) throws SQLException { 
try (Connection connection = dataSource.getConnection()) {
connection.setAutoCommit(false);

try (PreparedStatement statement = connection.prepareStatement(SQL)) {
// ...

try {
connection.commit();
} catch (SQLException e) {
connection.rollback();
throw e;
}
}
}
}

关于java - 多次重用 PreparedStatement,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2467125/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com