mybatis xml 文件中处理参数引号,避免 sql 注入与解析错误
在使用 MyBatis 时,XML 文件中的 SQL 参数处理,尤其包含特殊字符(如引号)时,容易引发 SQL 注入或解析错误。本文将通过一个案例,讲解如何在 MyBatis XML 文件中安全地处理参数引号。
问题:
使用 MyBatis 查询 tb_goods 表,条件是 fulldiscountreductionid 字段(存储 json 数组)包含特定值。数据库直接执行 SQL 语句正常,但在 MyBatis XML 文件中却出错。这是因为 XML 和 SQL 对引号的处理方式不同,导致参数传递错误。
错误的 XML 代码片段:
<select id="selectGoods" resultType="com.example.Goods"> select * from tb_goods <where> <if test="fulldiscountreductionid != null"> json_contains(full_discount_reduction_id_list, #{fulldiscountreductionid}) </if> </where> </select>
数据库可执行的 SQL 语句:
select * from tb_goods where json_contains(full_discount_reduction_id_list, '"1615237656678371329"');
#{fulldiscountreductionid} 会在参数周围添加单引号,导致 SQL 语法错误。
解决方案:
为了避免这个问题,应使用${} 代替 #{ } 直接将参数嵌入 SQL 语句中。
正确的 XML 代码片段:
<select id="selectGoods" resultType="com.example.Goods"> select * from tb_goods <where> <if test="fullDiscountReductionId != null"> JSON_CONTAINS(full_discount_reduction_id_list, ${fullDiscountReductionId}) </if> </where> </select>
使用 ${} 可以避免 MyBatis 自动添加单引号。
安全警告:
使用 ${} 会增加 SQL 注入风险。 务必对所有用户输入的参数进行严格的验证和过滤,以防止 SQL 注入攻击。 建议优先使用预编译语句 (#{ }),并结合合适的参数类型和输入校验来保证安全性。 只有在无法使用预编译语句的情况下,才谨慎考虑使用 ${} ,并做好充分的安全防护措施。
本例中,如果 fullDiscountReductionId 来自用户输入,必须在 Java 代码中进行严格的输入验证和转义处理,确保其安全后再传递给 MyBatis。 例如,可以使用正则表达式或其他安全方法来过滤掉潜在的恶意代码。