Javaで変数をデータベースに挿入する前に変数をエスケープするための推奨される方法は何ですか?
私が理解しているように、データをエスケープするために PreparedStatement.setString() を使用できますが、同じクエリを二度と実行する予定がない場合、PreparedStatement はやや非現実的です..すべてのクエリを準備せずに実行するより良い方法はありますか?
Javaで変数をデータベースに挿入する前に変数をエスケープするための推奨される方法は何ですか?
私が理解しているように、データをエスケープするために PreparedStatement.setString() を使用できますが、同じクエリを二度と実行する予定がない場合、PreparedStatement はやや非現実的です..すべてのクエリを準備せずに実行するより良い方法はありますか?
はい、すべてに準備済みステートメントを使用します。
それらは一度解析されます。
SQL インジェクション攻撃の影響を受けません。
SQL とその使用方法について考える必要があるため、これらはより優れた設計です。
それらが一度しか使用されていないと思うなら、あなたは全体像を見ていません. いつの日か、データまたはアプリケーションが変更されます。
編集。
プリペアド ステートメントで SQL について考えさせられるのはなぜですか?
文字列を組み立てる (または単純にテキストのリテラル ブロックを実行する) 場合、新しいPreparedStatement
オブジェクトは作成されません。SQL を実行しているだけです。非常に気軽に実行できます。
を作成 (および保存) するPreparedStatement
必要がある場合は、カプセル化、責任の割り当てについてもう少し考える必要があります。ステートメントの準備は、SQL 処理を行う前のステートフル イベントです。
余分な作業は小さいですが、重要ではありません。これが、人々が ORM やデータ キャッシング レイヤー、およびデータベース アクセスを最適化するためのそのようなものについて考え始める原因となっています。
プリペアド ステートメントを使用すると、データベースへのアクセスがカジュアルではなくなり、より意図的になります。
文字列連結を使用して自分で SQL クエリを作成しないでください。SQL クエリを作成するときは、変数やユーザー データを手動でエスケープしないでください。必要な実際のエスケープは、基礎となるデータベースによって異なり、ある時点で誰かがエスケープを忘れるでしょう。
要点は次のとおりです。準備済みステートメントでは、SQL 注入可能ステートメントを作成することはできません。カスタムエスケープを使えば可能です。選択は明らかです。
声明の準備はそれほど高価ではありません。ほとんどの代替手段よりも安全です。
プリペアドステートメントはプレーンステートメントよりも少し余分なオーバーヘッドがかかるという議論を聞いたことがあります。ユーザー入力をクエリに連結しない場合は安全であるはずです。これは本当かもしれませんが、追加コストはそれほど多くなく、SQLクエリは時間とともに変化します。クエリがインジェクションプルーフであることを自分自身に証明したために今日ステートメントを使い始めた場合、メンテナンスプログラマーがユーザー入力を受け入れるようにSQLを変更した日に、失敗の準備をしていることになります。そのステートメントをPreparedStatementに変更することを考えてください。私のアドバイスは、常にPreparedStatementを使用して、問題が見つかる前に問題を回避することです。
さらに良いことに、JDBC API を直接使用しないでください。エラーが発生しやすいためです (たとえば、あらゆる場合にすべてのリソースを適切にクリーンアップできないなど)。Spring の JdbcOperations インターフェースなどの JDBC ヘルパー オブジェクトを使用すると、コードのサイズとバグが大幅に削減されます。この 1 つの機能だけに Spring を使用する場合でも、JDBC API を直接使用する場合と比較して、非常に有利です。