sql防注入 | 底层 | jdbc类型转换 | 当简单类型参数 | |
$ | 不防止 | Statment | 不转换 | value |
# | 防止 | preparedStatement | 转换 | 任意 |
除模糊匹配外,杜绝使用${}
MyBatis教程,大家可以借鉴
1、#{} 是预编译处理,${} 是直接替换;
2、${} 存在SQL注入的问题,而 #{} 不存在;
#{}?是预编译处理,像传进来的数据会加个" "(#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号)
${}?就是字符串替换。直接替换掉占位符。$方式一般用于传入数据库对象,例如传入表名.
使用 ${} 的话会导致 sql 注入。什么是 SQL 注入呢?
比如 select * from user where id = ${value}? ? ? ? value 是一个数值。
如果对方传过来的是 001 ?and name = tom。这样就相当于多加了一个条件,把SQL语句直接写进来了。如果是攻击性的语句,则会导致数据库损坏。
所以为了防止 SQL 注入,能用 #{} 的不要去用 ${}。如果非要用 ${} 的话,那要注意防止 SQL 注入问题,可以手动判定传入的变量,进行过滤,一般 SQL 注入会输入很长的一条 SQL 语句。
方式一:直接替换
<select id="getUserById" resultType="com.by.pojo.User">
select * from user where username like '%${key}%'
</select>
方式二:使用concat进行字符串拼接
<select id="getUserById" resultType="com.by.pojo.User">
select * from user where username like concat('%', '${key}', '%')
</select>
<select id="getUserById" resultType="com.by.pojo.User">
select * from user where username like concat('%', #{key}, '%')
</select>
使用 #{} 传入的参数会自带引号
<select id="getUserById" resultType="com.by.pojo.User">
select * from user where username like concat('%', #{key}, '%')
</select>
目标sql 语句:select * from user where username = '%张%';
实际sql语句:select * from user where username = '%' 张 '%';