Spring NamedParameterJDBCTemplate重用Prepared Statements

时间:2012-08-28 16:28:48

标签: java spring jdbc jdbctemplate spring-jdbc

我正在使用Spring NamedParameterJdbcTemplate从表中获取一些值。出于某种原因,查询在我的Java应用程序中运行速度非常慢,而不是在SQL Management Studio上运行相同的查询。我也注意到在分析器中,准备好的语句不会被重用。如果我多次在我的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;

1 个答案:

答案 0 :(得分:11)

查看Spring NamedParameterJdbcTemplate的源代码,它将您的SQL解析为结构ParsedSql,然后用问号替换您的命名参数,然后构建PreparedStatement并填充它与您的参数。

它缓存ParsedSql条目,但始终构建新的PreparedStatements,因此最终不会在JDBC驱动程序级别重用这些条目。

PreparedStatement比常规Statement有两个优势:

  1. 使用方法向SQL添加参数,而不是在SQL查询本身中执行。通过这种方式,您可以避免SQL注入攻击,并让驱动程序为您进行类型转换。

  2. 正如您所说,可以使用不同的参数调用相同的PreparedStatement,并且数据库引擎可以重用查询执行计划。

  3. 似乎NamedParameterJdbcTemplate帮助你获得第一个优势,但对后者没有任何帮助。