在将 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/