ホームページ >Java >&#&チュートリアル >複数回の反復で PreparedStatement の再利用を最適化する方法
複数の反復による 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();
2 番目のアプローチでは効率がわずかに向上しますが、より優れたソリューションはバッチ実行にあります。
<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 ドライバーが提供するバッチ機能を利用し、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 中国語 Web サイトの他の関連記事を参照してください。