多次重用PreparedStatement如果将PreparedStatement与没有任何池的单个公共连接一起使用,我是否可以为每个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();我的问题是因为我想把这段代码放到多线程环境中,你能给我一些建议吗?谢谢
2 回答

慕虎7371278
TA贡献1802条经验 获得超4个赞
第二种方式更有效,但更好的方法是批量执行它们:
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. } } }}
对于多线程环境,如果使用try-with-resources语句按照常规JDBC惯用法获取并关闭同一方法块内最短可能范围内的连接和语句,则无需担心这一点,如下所示:片段以上。
如果这些批处理是事务性的,那么您希望关闭连接的自动提交,并且只在所有批处理完成时提交事务。否则,当第一批批次成功而后者不成功时,可能会导致脏数据库。
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; } } }}
添加回答
举报
0/150
提交
取消