接続プールを使用せずに単一の接続で PreparedStatement を操作する場合、開発者は多くの場合、新しいステートメントを作成するというジレンマに直面します。 DML/SQL 操作ごとにインスタンスを作成するか、既存のインスタンスを再利用します。ここでは、両方のアプローチの長所と短所を分析し、効率とスケーラビリティを向上させるための代替ソリューションを検討します。
最初のアプローチには、操作ごとに新しい PreparedStatement インスタンスを再作成することが含まれます。各ステートメントに、以前の実行による残留パラメーターや状態が含まれていないことを確認します。ただし、このアプローチは、特にマルチスレッド環境でパフォーマンスの低下につながる可能性があります。
2 番目のアプローチは、単一の PreparedStatement インスタンスを再利用し、各実行前にそのパラメーターをクリアすることで、これらの問題に対処します。この方法はいくらか効率的ではありますが、最初のアプローチの洗練さとシンプルさに欠けています。
複数の DML/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>
実行されるバッチの数が過剰なシナリオでは、バッチ サイズを制限すると、パフォーマンスがさらに向上します。
<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 を取得して閉じることで軽減されます。
<code class="java">try ( Connection connection = dataSource.getConnection(); PreparedStatement statement = connection.prepareStatement(SQL); ) { // ... }</code>
トランザクション シナリオでは、接続の自動コミットを無効にすると、すべてのバッチが完了した後にのみトランザクションをコミットするため、データの整合性が確保されます。
<code class="java">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; } } } }</code>
バッチ実行を活用し、適切な接続管理手法を遵守することにより、を使用すると、開発者は、マルチスレッド環境であっても、効率とスケーラビリティを最大化しながら、PreparedStatements のパワーを活用できます。
以上がPreparedStatement の再利用: 再利用するか否か?効率とスケーラビリティの詳細の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。