8

Spring NamedParameterJdbcTemplateを使用して、テーブルからいくつかの値をフェッチしています。何らかの理由で、SQL Management Studioで同じクエリを実行するのとは対照的に、Javaアプリではクエリの実行が非常に遅くなります。また、プロファイラーで、準備されたステートメントが再利用されないことに気づきました。JAVAアプリで同じクエリを複数回実行すると、異なるプリペアドステートメントが実行されているのがわかります。したがって、ステートメントが再利用されない理由がわかりません。クエリでIN句を使用しているため、パフォーマンスが低下しますか?

これが私のサンプルJavaコードです

StringBuilder vQuery = new StringBuilder();
vQuery.append(" SELECT SUM(Qty) FROM vDemand");
vQuery.append(" WHERE ProductID = :ProductID");
vQuery.append(" AND [Date] >= :StartDate AND [Date] <= :EndDate");
vQuery.append(" AND CustomerID IN ( :CustomerID )");

MapSqlParameterSource vNamedParameters = new MapSqlParameterSource();
vNamedParameters.addValue("ProductID", aProductID);
vNamedParameters.addValue("CustomerID", aCustomerlIDs);
vNamedParameters.addValue("StartDate", aDate, Types.TIMESTAMP);
vNamedParameters.addValue("EndDate", aDate, Types.TIMESTAMP);

int vTotalQuantity = this.getNamedParameterJdbcTemplate().queryForInt(vQuery.toString(), vNamedParameters);
return vTotalQuantity;
4

1 に答える 1

13

Springのソースコードを見ると、NamedParameterJdbcTemplateSQLが構造に解析され、ParsedSql名前付きパラメーターが疑問符に置き換えられてから、が作成PreparedStatementされ、パラメーターが入力されます。

エントリをキャッシュしParsedSqlますが、常に新しくビルドPreparedStatementsされるため、最終的にこれらはJDBCドライバレベルで再利用されません。

APreparedStatementには、通常よりも2つの利点がありStatementます。

  1. SQLクエリ自体の内部ではなく、メソッドを使用してSQLにパラメータを追加します。これにより、SQLインジェクション攻撃を回避し、ドライバーに型変換を実行させることもできます。

  2. あなたが言ったように、同じPreparedStatementものを異なるパラメータで呼び出すことができ、データベースエンジンはクエリ実行プランを再利用できます。

それNamedParameterJdbcTemplateは最初の利点であなたを助けるようですが、後者には何もしません。

于 2012-08-28T17:06:26.747 に答える