MyBatis中动态sql是其主要特性之一,在 mapper 中定义的参数传到 xml 中之后,在执行操作之前 mybatis 会对其进行动态解析。
MyBatis提供了两种支持动态 sql 的语法:#{} 以及 $ {},其最大的区别则是#{}方式能够很大程度防止sql注入(安全),${}方式无法防止Sql注入。
${}方式是将形参和SQL语句直接拼接形成完整的SQL命令后,再进行编译。所以可以通过设计形参变量的值,从而改变SQL语句产生安全隐患,即为SQL注入攻击。举例说明:
在Mapper映射文件中:
<select id="findByName" parameterType="String" resultMap="ResultMap">
SELECT * FROM user WHERE username='${value}'
select>
当username=" ‘or 1=1 or’ "传入后,${}将变量内容直接和sql语句进行拼接。
SELECT * FROM user WHERE username='' OR 1=1 OR '';
该跳语句可以将整个数据库用户内容暴露出来。
#{}方式则是先用占位符代替参数将SQL语句先进行编译,然后再讲参数中的内容替换进去。因为SQL语句已经被预编译过,其SQL意图将无法通过非法的参数内容实现更改,其参数中的内容,无法变为SQL命令的一部分。
故,#{}可以防止SQL注入而${}却不行