2012-03-03 21 views
6
は多くの場合、ネットワーク内でこのようなコードを見つけることができます

。どうして?
私が知っているように、PreparedStatementはSQL文のプリコンパイルに時間を費やします。 StatementがPreparedStatementより速くなることが分かります。または私は間違っている?これは速いですか?</p> <pre><code>private static final String SQL = "SELECT * FROM table_name"; .... </code></pre> <p>をして、このSQLクエリのPreparedStatementを使用している:StatementまたはPreparedStatementの

答えて

11

などです。同じステートメントを複数回、異なるデータで実行する必要がある場合は、準備済みステートメントの方がはるかに高速です。 SQLはクエリを一度しか検証しないため、文を使用すると、そのたびにクエリが検証されます。

PreparedStatementsを使用するもう1つの利点は、SQLインジェクションの脆弱性を回避することです。あなたのケースではクエリがそれほど簡単ではありません。

準備された文の実行と文の実行の違いは、おそらくごくわずかです。

EDIT:下記のコメントに応じて、DAOクラスをよく調べて、何をしているのかを確認する必要があります。たとえば、メソッドが呼び出されるたびにプリペアドステートメントを再作成すると、プリペアドステートメントを使用するメリットが失われます。

達成したいのは、永続性レイヤーをカプセル化して、MySQLやPostgresなどの特定の呼び出しを使用しないようにすることです。同時に、次のようなパフォーマンスやセキュリティの利点を活用します。準備されたステートメント。これを行うには、PreparedStatementなどのJava自身のオブジェクトに依存する必要があります。

私は個人的には、Hibernateの下でCRUD操作を行うための独自のDAOクラスを構築し、Java Persistence APIを使用してすべてをカプセル化し、セキュリティ上の利点については準備済みのステートメントを使用する必要があります。反復操作を行うための具体的なユースケースがある場合は、そのオブジェクト内でラップする傾向があります。

Hibernateは、XMLファイル経由で使用しているデータベースベンダーを使用するように設定することができます。したがって、パーシスタンスレイヤのカプセル化は本当にすっきりしています。しかし、それは正しくなるにはかなり複雑な製品です!

+0

私は何かを明確にしたいと思います。私の簡単なwebAppにはDAOクラスがあります。このクラスでは、prepareStatementを使うメソッド(IDで情報を取得する)があります。このメソッドを複数回呼び出す場合、preparedStatementがこのSQLクエリをプリコンパイルする回数は何回ですか? – Ifozest

+0

私はこのために私の主な答えを編集しました - それはあなたの質問の興味深い部分です。 – christophmccann

+1

編集を参照してください。詳細な回答をいただきありがとうございます。 – christophmccann

4

ほとんどの場合、クエリはあなたの例ほど単純ではありません。クエリにバリエーションがある場合、つまりコンパイル時に知られていないパラメータは、PreparedStatementを使用してSQLインジェクションの脆弱性を回避する必要があります。これはパフォーマンス上の問題に優先します。 PreparedStatementとStatementとの間に相違がある場合、問題の特定のJDBCドライバに大きく依存します。ほとんどの場合、データベースにアクセスして実際のクエリを実行して結果を取得するコストと比較して、ペナルティは無視できる程度です。

+0

はい、あなたは明白なことを言う。しかし、このクエリでは、パラメータを設定する必要はなく、それに基づいてSQLインジェクションは行いません。 – Ifozest

+1

だから、パラメータがなくても一度だけ実行すると、PreparedStatementの代わりにStatementを実行する方が少し速いかもしれないが、PreparedStatementを常に使用しています。 –

0

私の知る通りPreparedStatementは非常に高速です。ここでなぜpreparedstatementが速いのか何らかの理由でステートメントを読んでください。
JDBC APIは、データベースとの接続機能を提供します。次に、ステートメントとpreparedstatementを使用してクエリを実行しようとします。
クエリを実行するステップは4つあります。

SQLクエリの解析。
このクエリをコンパイルします。
データ取得パスの最適化。
クエリを実行します。

ステートメントインターフェイスは、クエリを複数回実行する必要がない場合に適しています。

Statement Interfaceの短所。 ハッカーは簡単にデータをハックすることができます。私たちはユーザー名とパスワードを持っている1つのクエリを持っていると仮定すると、あなたは適切なパラメータを与えることができるパラメータですusername = '[email protected]'とパスワード= 'abc123'実際にはこれは現在しかし、ハッカーはusername = 'abc @ example.com 'または' 1 '= 1およびpassword =' 'を指定すると、正常にログに記録できます。これはステートメントで可能になっています。
そして、sqlはデータベースからデータを取得するたびに検証します。

Javaには、上記のPreparedStatementという問題の解決策があります。 このインターフェイスには多くの利点があります。 preparedstatementの主な利点は、SQLは毎回クエリを検証しないということです。結果を迅速に得ることができます。以下の準備文の利点をお読みください。

1)クエリのパラメータの値をsetterメソッドで安全に指定できます。 2)自動的に特殊文字をエスケープするため、SQLインジェクションを防止します。 3)上記のステートメントを使用すると、毎回4つのステップが実行されますが、PreparedStatementを使用するときは最後のステップのみが実行されるので、これはより高速です。

関連する問題

 関連する問題