Spring NamedParameterJDBCTemplate重用Prepared Statements
我使用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;
查看Spring的NamedParameterJdbcTemplate
的源代码,它将您的SQL解析为ParsedSql
结构,然后用问号替换您的命名参数,然后构建PreparedStatement
并用您的参数填充它。
它缓存ParsedSql
条目,但始终构建新的PreparedStatements
因此最终不会在JDBC驱动程序级别重用这些条目。
PreparedStatement
比常规Statement
有两个优点:
-
您可以使用方法向SQL添加参数,而不是在SQL查询本身中执行此操作。 通过这种方式,您可以避免SQL注入攻击,并让驱动程序为您进行类型转换。
-
正如您所说,可以使用不同的参数调用相同的
PreparedStatement
,并且数据库引擎可以重用查询执行计划。
似乎NamedParameterJdbcTemplate
可以帮助您获得第一个优势,但对后者没有任何帮助。