Spring NamedParameterJDBCTemplate重用Prepared Statements

use*_*587 7 java spring jdbc spring-jdbc jdbctemplate

我使用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;
Run Code Online (Sandbox Code Playgroud)

Luc*_*ano 12

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

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

A PreparedStatement比常规有两个优点Statement:

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

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

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

  • 我认为这是一个不同的问题,请检查jdbc驱动程序的配置.使用驱动程序和仅执行查询的Main方法创建一个新项目,即纯SQL.慢50倍是太多了. (2认同)