5

準備済みステートメントを使用したい。準備済みステートメントの利点は、毎回解析/コンパイルする必要がないため、負荷が軽減されることです。ここで私の質問は、既に準備されたステートメントの「認識」が Java または DB システム内でどこで行われるかということです。コード内の PreparedStatement オブジェクトを格納する場所を知りたいので、質問します。クラス属性として、すべてのリクエストでパラメーターを設定するか、リクエストがあるたびに新しい準備済みステートメント オブジェクトを作成します。

    public class Option1 {
       private PreparedStatement myStatement;
       public Option1() {
          // create the myStatement object
          myStatement = conn.prepareStatement("");
       }
       public List<Items> query() {
          // just use the myStatement object
          myStatement.setString(1, "foo");
       }
   }

    public class Option2 {
       public List<Items> query() {
          PreparedStatement myLocalStatement = conn.prepareStatement("");;
          // create and use the statement
          myLocalStatement.setString(1, "foo");
       }
   }

今私の質問は、それを行うためのより良い方法、オプション1または2は何ですか? ただし、実行するたびに「クリーンアップ」を行う必要がありmyStatement.close()ます。

別の言い方をすればいいのかもしれませんが、最も効果的な方法で再利用するにはどうすればよいでしょうか?

更新: 2 つの回答がある場合、1 つはオプション 1 を、もう 1 つはオプション 2 を優先し、コミュニティにその選択に投票するようお願いします ^^

4

4 に答える 4

5

whereSQL データベースは、完全なクエリ (句を含む) をキーとしてステートメントの実行計画をキャッシュしています。準備済みステートメントを使用すると、使用している値に関係なく、クエリは同じになります (値は常に「?」です)。

したがって、データベース キャッシュの観点からは、2 つのオプションに違いはありません。Java EE 固有の問題についても説明しているこの記事を参照してください。

しかし、もちろん、他の人が述べたように、特にコードを頻繁に再利用している場合 (この例のように)、コードの観点からは他にもいくつかの要因があります。重要なことは、一部の JDBC ドライバーがプリコンパイルをサポートしていることです。
プリペアド ステートメントは最初はオーバーヘッドがかかり、その後のすべての使用に追いつくことに注意してください。これについては、すばらしい章があります。

于 2012-09-03T09:01:17.307 に答える
2

オプション2をお勧めします

public class Option2 {
   public List<Items> query() {
      PreparedStatement myLocalStatement = conn.prepareStatement("");;
      // create and use the statement
      myLocalStatement.setString(1, "foo");
   }
}

あたかも論理ユニットが多くのメソッドとデータメンバーに分散されているかのように、障害点が増加し、エラーが発生しやすくなります。

または、次のようにします。

public class Option2 {
   public List<Items> query(String sql, String parameter) {
      PreparedStatement myLocalStatement = conn.prepareStatement(sql);
      // create and use the statement
      myLocalStatement.setString(1, parameter);
   }
}

次のように使用します。

Option2 myQuery = new Option2();
myQyery.query("SELECT * FROM PERSON WHERE NAME = :?","ANY_NAME");
于 2012-09-03T08:54:32.207 に答える
1

私はオプション1に行きます:つまり。

public class Option1 {
       private PreparedStatement myStatement;
       public Option1() {
          // create the myStatement object
          myStatement.setString(1, "foo");
       }
       public List<Items> query() {
          // just use the myStatement object
       }
   }

理由: 必要に応じて新しいオブジェクトを割り当てることができます。このようなことをすることで

pst = con.prepareStatement(myQuery);関数では、あなたの場合、関数はOption1()

于 2012-09-03T08:54:06.543 に答える