JdbcTemplate 不支持参数化查询“IN"的情况?必须按 NamedParameterJdbcTemplate 吗?
为了防止 SQL 注入攻击,我项目中的所有 SQL 语句代码都应该转换为参数化查询.但是当查询条件包含IN"案例时,我遇到了问题.像这样(使用 DB2 数据库):
Aimed at preventing SQL injection attacks, all the SQL Statement code in my project should transformed to Parameterized Query. But I got a problem when the query condition includes a 'IN' case. Like this (Using DB2 database):
String employeeId = 'D2309';
String name = "%brady%";
List<Integer> userRights = new ArrayList<Integer>();
userRights.add(1);
userRights.add(2);
userRights.add(3);
String sql = "SELECT * FROM T_EMPLOYEE WHERE EMPLOYEE_ID = ? AND NAME LIKE ?
AND RIGHT IN (?)";
jdbcTemplate.query(sql, new Object[] {employeeId, name, userRights}, new
EmployeeRowMapper());
以上代码运行失败,出现异常:
The above code runs failed with the exception:
org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad
SQL grammar [SELECT * FROM T_EMPLOYEE WHERE EMPLOYEE_ID = ? AND NAME LIKE ? AND
RIGHT IN (?)]; nested exception is com.ibm.db2.jcc.am.io: [jcc][1091][10824]
[3.57.82] .... ERRORCODE=-4461, SQLSTATE=42815
这里的问题是 JdbcTemplate 不支持 IN case 的参数化查询吗?我知道这项工作可以通过NamedParameterJdbcTemplate来完成,是否只有NamedParameterJdbcTemplate可以做IN case查询?
The question here is that does not JdbcTemplate support Parameterized Query for IN case? and I know this work can be done by NamedParameterJdbcTemplate, and whether only NamedParameterJdbcTemplate can do IN case query?
非常感谢.
推荐答案
正如我在评论中已经提到的,我对这个解决方案并不满意,因为它会动态生成许多 SQL 语句.鉴于 userRights
的数量介于 1 和 n 之间,它需要在缓存中最多 n 个准备好的语句.
As I already mentioned in the comments, I'm not happy with this solution as it dynamically generates a number of SQL statements. Given the number of userRights
is between 1 and n, it requires up to n prepared statements in the cache.
以下应该可以工作(我没有尝试过).
The below should work (I did not try it).
String employeeId = 'D2309';
String name = "%brady%";
List<Integer> userRights = new ArrayList<Integer>();
userRights.add(1);
userRights.add(2);
userRights.add(3);
// build the input string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < userRights.size; i++) {
sb.append("?");
if (i < userRights.size() - 1) {
sb.append(", ");
}
}
// build the SQL
String sql = "SELECT * FROM T_EMPLOYEE WHERE EMPLOYEE_ID = ?" +
" AND NAME LIKE ?" +
" AND RIGHT IN (" + sb.toString() + ")";
// init the object array
// size is employeeId + name + right
Object[] param = new Object[2 + userRights.size()];
// fill it
param[0] = employeeId;
param[1] = name;
for (int i = 0; i < userRights.size(); i++) {
param[i + 2] = userRights.get(i);
}
jdbcTemplate.query(sql, param, new EmployeeRowMapper());
相关文章