2

为了避免我的项目中的 SQL 注入攻击,我正在尝试使用参数化查询方式访问数据库。现在我知道如何处理如下相同的情况(使用 Spring JdbcTemplate):

String sql = "SELECT * FROM T_USER WHERE USERNAME = ? AND PASSWORD = ?"
jdbcTemplate.query(sql, 
                   new UserRowMapper(), 
                   new Object[]{"%admin%", "%password%"});

上面的代码运行没有问题,但我不知道如何处理“IN”的情况,以下是我的情况,它工作失败:

String sql = 
   "SELECT * FROM T_USER WHERE USERNAME = ? AND PASSWORD = ? AND CLASS_ID IN (?)"
jdbcTemplate.query(sql, 
                   new UserRowMapper(), 
                   new Object[]{"%admin%", "%password%", "1,2,3"});

有人给我指导吗?非常感谢。

4

2 回答 2

1

我认为您可以创建一个列表并将其作为第三个参数传递。LIKE此外,您需要=在前两列过滤器中使用。

List<Integer> classIds = new ArrayList<Integer>();
classIds.add(1);
classIds.add(2);
classIds.add(3);

String sql = "SELECT * FROM T_USER WHERE "+
              "USERNAME LIKE ? AND PASSWORD LIKE ? AND CLASS_ID IN (?)";
jdbcTemplate.query(sql, new Object[]{"%admin%", "%password%", classIds},
                                                         new UserRowMapper());

请注意:以下是语法:

public List query(String sql, Object[] args, RowMapper rowMapper) 
             throws DataAccessException

编辑:请尝试namedParameterJdbcTemplatebwlow:

String sql = "SELECT * FROM T_USER WHERE "+
           "USERNAME LIKE :uname AND PASSWORD LIKE :passwd AND CLASS_ID IN (:ids)";
 Map<String, Object> namedParameters = new HashMap<String, Object>();
 namedParameters.put("uname", "%admin%);
 namedParameters.put("passwd", "%password%");
 namedParameters.put("ids", classIds);
 List result = namedParameterJdbcTemplate.query(sql, namedParameters, 
                                                             new UserRowMapper());
于 2012-11-02T04:10:13.920 回答
0

三个选项:

  1. 为 IN LIST 的每个长度生成不同的 JDBC 查询,并参数化每个 INDIVIDUAL 项目,例如这个答案
  2. 对于小桌子,您可以作弊并使用 LIKE 语句,例如这个答案
  3. 使用 SPLIT 函数(反 LISTAGG)将分隔列表转换为每列一列的单独行,并对其进行 JOIN。示例 SPLIT 函数
    • 您会将函数的参数参数化为单个字符串
于 2012-11-02T04:04:39.633 回答