2011-01-10 17 views
6

We all knowthatループ内で新しいインスタンスを作成するよりも、JDBC PreparedStatementを再利用するべきです。メソッド間でPreparedStatementを再利用するか?

しかし、異なるメソッド呼び出し間でPreparedStatementを再利用する方法を教えてください。 再使用 - 「ルール」はまだカウントされますか?

フィールドをPreparedStatementに使用することを本当に考慮する必要がありますか、またはすべての呼び出しでプリペアドステートメントを閉じて再作成する必要がありますか(ローカルにする)? (もちろん、そのようなクラスのインスタンスはConnectionにバインドされていることがありますが、これは一部のアーキテクチャでは不都合かもしれません)

私は理想的な答えは「それに依存する」かもしれないと認識しています。
しかし私は経験の浅い開発者のためのベストプラクティスを探しています。ほとんどの場合、適切な選択をします。もちろん

+3

間違いなく、クラスのフィールドにしないでください。メソッドローカルにしておきます。 – BalusC

答えて

13

ようなクラスのインスタンスは以下のようになります

不利かもしれない接続にバインドされるのでしょうか?それは巨大な不利益です。あなたはそれへのアクセスを同期させる必要があります。これは、マルチユーザのパフォーマンスを犠牲にしたり、複数のインスタンスを作成してプールに保持したりします。お尻の大きな痛み。

ステートメントプーリングはJDBCドライバの仕事であり、ほとんどの場合、すべてではないにしても、現在のドライバの作物のほとんどがこれを行います。 prepareStatementまたはprepareCallを呼び出すと、ドライバは既存のリソースとプリコンパイル済みステートメントの再利用を処理します。

Statementオブジェクトは接続に関連付けられており、接続はできるだけ早く使用してプールに戻す必要があります。要するに

は、次に、ループ内で繰り返し、それを使用して、方法の開始時PreparedStatementを得る方法の最後でそれを閉じる標準的、ベストプラクティスです。

+0

なぜこれが大したことではないのですか? Connectionごとに1つのスレッドがあります。あなたのCRUDメソッドを含む各サービスクラスは、PreparedStatementsを構築し、それらをすべてのメソッドに再利用します。 PreparedStatementは、接続が閉じられると閉じます。 – Gili

0

はい、再利用できますが、同じConnectionオブジェクトが使用されている場合にのみカウントされ、データベース接続プール(Webアプリケーション内など)を使用している場合はConnectionオブジェクトが潜在的になります毎回違う。

この理由から、Webアプリケーション内で使用する前に常にPreparedStatementを再作成します。

接続プールを使用していない場合、あなたは金色です!

0

違いは見当たりません:同一の接続に対して同じ文を繰り返し実行すると、PreparedStatementは何らかの形で再利用してみませんか?複数のメソッドが同じステートメントを実行する場合、そのステートメントを独自のメソッド(または独自のクラス)にカプセル化する必要があります。そうすれば、PreparedStatementを回る必要はありません。

+1

PreparedStatementは特定のConnectionに「所属」しているため、異なる接続間で再利用することはできません。もちろん、さまざまな接続に沿って実行されるコードを再利用することもできますが、PreparedStatmentの準備は一度準備してから再利用することです。別のConnectionを使用すると不可能です。 –

6

多くのデータベース作業負荷は、IOバインドではなくCPUバインドです。つまり、SQLクエリの解析や、ディスクへのアクセスに費やすよりも、(実行計画を実行する)SQLクエリの処理方法の把握など、データベースの処理に費やす時間が長くなります。これは「トランザクション」ワークロードの方が「レポート」ワークロードよりも真実ですが、どちらの場合も、計画の準備に費やされる時間は予想以上に長くなる可能性があります。

ステートメントが頻繁に実行され、PreparedStatementsをメソッド呼び出しの間にキャッシュする手間が開発者にとって価値がある場合は、常に良いアイデアです。いつものようにパフォーマンスは重要ですが、測定は重要ですが、安く十分に行うことができれば、PreparedStatementを習慣から守ってください。

一部のJDBCドライバおよび/または接続プールでは、透過的な「prepared statement caching」が提供されているので、自分で行う必要はありません。特定の選択された透過キャッシング戦略の動作を理解している限り、それを追跡することは可能です。本当に避けたいのは、データベースのヒットです。

+0

データベースにたくさんのIOを必要とする多くの正常なクエリがあります。具体的には、大きなデータセットの計算/集約/ ...を行うもの。 –

+0

@Jochaim Sauer:私は自分の発疹アサーションを修飾しました:-) –

関連する問題