当前位置: 首页 > 面试题库 >

JdbcTemplate不支持参数化查询“ IN”的情况?必须通过NamedParameterJdbcTemplate吗?

左恺
2023-03-14
问题内容

为了防止SQL注入攻击,我项目中的所有SQL语句代码都应转换为参数化查询。但是当查询条件包含“ IN”情况时,我遇到了一个问题。这样(使用DB2数据库):

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());

上面的代码运行失败,但有以下例外:

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情况下的参数化查询吗?我知道可以通过NamedParameterJdbcTemplate来完成这项工作,是否只有NamedParameterJdbcTemplate可以进行案例查询?

非常感谢。


问题答案:

正如我在评论中已经提到的那样,我对这种解决方案不满意,因为它动态生成大量SQL语句。给定数量userRights在1到n之间,则高速缓存中最多需要n个准备好的语句。

下面应该工作(我没有尝试过)。

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());


 类似资料:
  • 我是Spring3的初学者。我正在学习Spring DAO支持。我想知道名参数JdbcTemplate和JdbcTemplate之间的区别。从性能来看,哪一个是最好的。以及何时选择命名参数JdbcTemplate,何时选择JdbcTemplate。

  • 我遇到了一个奇怪的问题,使用Oracle Pivot语法的sql查询。我可以毫无问题地在SqlDeveloper中运行查询;然而,使用行映射器通过JdbcTemplate运行它会产生关于无效列名的奇怪错误。 SQL语句: 行映射器: DAO调用类:

  • 问题内容: 我正在将几个已硬编码到应用程序中的查询转换为动态的参数化查询。我遇到一个特定的查询,该查询有一个子句: 第一个参数很简单,因为它只是一个普通参数: 但是,第二个参数是一个整数列表,表示需要更新的行的ID。如何为单个参数传递整数列表?或者,您将如何设置此查询,以使您不必每次调用时都完全构建它,并且可以防止SQL注入攻击? 问题答案: 您可以基于(可能)可变数量的参数“动态”构建参数化查询

  • 我试图在我的存储库中编写一个类似的查询方法 在执行代码时,我遇到了以下错误: 组织。postgresql。util。PSQLException:无法推断用于java实例的SQL类型。时间瞬间使用带有显式类型值的setObject()指定要使用的类型。 我是忘记了什么,还是Spring Data Jdbc根本不支持使用Instant作为参数?如果有,将来是否计划提供这种支助?

  • 在Spring数据JPA中,不使用方法参数就可以通过布尔属性进行查询吗? 基本上,我希望这个工作不使用自定义@查询注释:

  • 问题内容: 我很难使用MySQLdb模块将信息插入到我的数据库中。我需要在表中插入6个变量。 有人可以帮我这里的语法吗? 问题答案: 提防对SQL查询使用字符串插值,因为它不能正确地转义输入参数,并使您的应用程序容易受到SQL注入漏洞的影响。 这种差异看似微不足道,但实际上它是巨大的 。 不正确(存在安全问题) 正确(带有转义符) 这增加了混乱,即用于绑定SQL语句中的参数的修饰符在不同的DB A