私はさまざまな場所を見て、PreparedStatement
からStatement
までの範囲が、パフォーマンスの利点のためだけであっても、好ましいとされるべきであるという不名誉な主張をたくさん聞いたことがあります。 PreparedStatement
は、バッチ処理のために排他的に使用されなければならないという主張に至るまで、単一の実行の後にPreparedStatementを閉じる - それは設計上の欠陥ですか?
しかし、(私が主にオンラインで行った)ディスカッションには盲点があるようです。私は具体的なシナリオを提示しましょう。
DB接続プールを備えたEDA設計のアプリケーションがあります。イベントが来て、その中には永続性が必要なものもあれば、そうでないものもあります。一部は人為的に生成されます(たとえば、X分ごとに更新/リセットなど)。 いくつかのイベントが発生し、順番に処理されますが、永続性を必要とする他のタイプのイベントも同時に処理できます。
人為的に生成されたイベントとは別に、永続性を必要とするイベントがどのように到着するかの構造はありません。
このアプリケーションはかなり前に設計され(約2005年)、いくつかのDBMSをサポートしています。典型的なイベントハンドラ(永続性が必要とされる):
- プール
- からの接続は、SQL文を準備します
- は
- プロセスの結果セット、該当する場合は、
- それを閉じ近いプリペアドステートメントを実行します準備されたステートメント
- 必要に応じて同じ方法で別のステートメントを作成する
- プールに戻る接続
イベントにバッチ処理が必要な場合は、文は一度作成され、addBatch
/executeBatch
のメソッドが使用されます。これは明白なパフォーマンス上の利点であり、これらのケースはこの質問に関連していません。
最近、私は、(解析)ステートメントを準備し、一度それを実行すると終了の全体的なアイデアは、PreparedStatement
の誤用が本質的であること、意見を受けているにかかわらず、サーバーかどうかのゼロパフォーマンス上の利点を提供し、 (Oracle、DB2、MSSQL、MySQL、Derbyなど)は、プリペアドステートメントキャッシュ(または少なくともデフォルトのJDBCドライバ/データソースではない)にそのようなステートメントを宣言することさえありません。
また、MySQLの開発環境でいくつかのシナリオをテストしなければならなかったので、Connector/J使用アナライザはこの考えに同意しているようです。接続ごとに任意のイベントで使用されるすべての単一のSQL文を保持しているPreparedStatement
インスタンスのキャッシュを持つ、
PreparedStatement created, but used 1 or fewer times. It is more efficient to prepare statements once, and re-use them many times
により、以前の概説アプリケーション設計の選択肢に:すべての非バッチ処理されたSQL文の場合、close()
プリントを呼び出します接続プール内の貧しい人々の選択肢のように聞こえる。
誰かがこれについて詳しく説明できますか? 論理 "準備実行(一度) - クローズ"に欠陥がありますか?、本質的に推奨されていませんか?
P.S.明示的にConnector/JのためのuseUsageAdvisor=true
とcachePrepStmts=true
を指定し、useServerPrepStmts=true
またはuseServerPrepStmts=false
すべての非バッチSQL文のclose()
PreparedStatement
上のインスタンスを呼び出すときに、まだ効率に関する警告につながるのいずれかを使用して。
'PreparedStatement'に渡されるパラメータはどこから来ますか?多くの場合、 'PreparedStatement'はユーザの入力に基づいてステートメントを構築することを避けるために使用され、ステートメントの構造(例えばSQLインジェクション)を破る可能性があります。 – RealSkeptic
はい、私は自動化入力墨塗りを認識しています。主に(整数)PKはイベントを伴います。時には生の入力(バイナリデータフィールドはフィールド型に基づいて解析され、 'setXxx'が挿入されます)、そうでなければ' setXxx'はグローバルまたはセッション(前述のシーケンシャルイベント)変数で呼び出すことができます。アプリケーション。しかし、疑問は、可能な副作用の可能性にかかわらず、単一のexec-then-closeロジックが推奨されていないかどうかです。 – afk5min
すべては、DBシステムとドライバの内容によって異なります。ほとんどのドライバー(およびプール)は、それらを閉じるときでさえ、ステートメントキャッシングを実行すると述べています。したがって、あなたが長いスレッドを処理しているスレッド(俳優スタイル)を持っていなければ、PSを閉じるパターンに従います(接続が戻ったときにプールがそれをとるため)。 PSを開いたままにすることの最大の問題は、現在の接続でのみ機能することです。そのため、接続も保持する必要があります。 – eckes