単一接続環境での PreparedStatement の再利用
接続プールのない単一の専用データベース接続がある状況では、次のことが可能です。プリペアド ステートメントの利点を維持しながら、DML/SQL 操作ごとに PreparedStatement の複数のインスタンスを作成できるかどうか疑問に思います。
オプション 1: 新しいインスタンスの作成
<code class="java">for (int i = 0; i < 1000; i++) { PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setObject(1, someValue); preparedStatement.executeQuery(); preparedStatement.close(); }
このアプローチではプリペアド ステートメントの機能は維持されますが、反復ごとに新しい PreparedStatement を作成して閉じるオーバーヘッドが発生します。
オプション 2: 単一インスタンスの再利用
<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();
このアプローチは、ステートメントを繰り返し準備するオーバーヘッドを排除するため、新しいインスタンスを作成するよりも若干効率的です。ただし、SQL インジェクションの脆弱性に対して、個別の PreparedStatement インスタンスを使用する場合と同じレベルの保護は提供されません。
バッチ処理による効率化
より最適な解決策は、バッチでの操作:
<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>
このアプローチでは、複数の操作を単一のバッチでデータベースに送信することで効率が大幅に向上します。特定の間隔 (1000 項目ごとなど) でバッチを実行することで、パフォーマンスをさらに最適化できます。
マルチスレッドに関する考慮事項
マルチスレッド環境で PreparedStatement を使用する場合、次のことが重要です。スレッドの安全性の問題を回避するために、可能な限り最短のスコープ内で接続とステートメントを取得して閉じます。これは、提供されたコード スニペットで示されているように、try-with-resources ステートメントを使用して同じメソッド ブロック内で実行する必要があります。
以上が単一接続環境で PreparedStatement を再利用できますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。