通过多次迭代重用PreparedStatement
如果在没有连接池的情况下使用单个公共连接,您可能会遇到以下问题为每个 DML 或 SQL 操作创建一个新的PreparedStatement实例是否更有效,同时保留准备好的语句的优点。
而不是:
<code class="java">for (int i=0; i<1000; i++) { PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setObject(1, someValue); preparedStatement.executeQuery(); preparedStatement.close(); }
您可以考虑:
<code class="java">PreparedStatement preparedStatement = connection.prepareStatement(sql); for (int i=0; i<1000; i++) { preparedStatement.clearParameters(); preparedStatement.setObject(1, someValue); preparedStatement.executeQuery(); } preparedStatement.close();
虽然第二种方法提供了轻微的效率提升,但更好的解决方案在于批处理执行:
<code class="java">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(); } }</code>
这种方法利用了 JDBC 驱动程序提供的批处理功能,减少了往返数据库并提高效率。您可以通过定义批量大小限制来进一步优化,例如每 1000 条执行:
<code class="java">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. } } } }</code>
对于多线程环境,您可以通过在最短的时间内获取并关闭连接和语句来确保线程安全使用 try-with-resources 语句的可能范围,如上面的代码片段所示。对于事务批次,禁用自动提交并仅在所有批次完成后提交事务。
以上是如何优化多次迭代的PreparedStatement重用?的详细内容。更多信息请关注PHP中文网其他相关文章!