MyBatis支持两种参数符号,一种是#,另一种是$。比如:
<select id="queryAll" resultMap="resultMap">
SELECT * FROM NEWS WHERE ID = #{id}
</select>
<select id="queryAll" resultMap="resultMap">
SELECT * FROM NEWS WHERE ID = ${id}
</select>
#{}速度快,能防止sql注入,是占位符方式,先预编译,然后填充参数,字符串格式,相当于填空题 用户名=(___),参数只是下划线上的内容
${}是直接拼接到语句上,执行语句,对于上面那道填空题 ,这种方式需要自己拼括号和参数,但是也可以拼接想执行的任何语句,也就是传说中的sql注入
我们在日常使用中应该尽量使用#{},但是在某些情况下不得不使用${}这个时候就需要特别注意sql注入的问题。
1.模糊查询
错误示例:
Select * from news where title like ‘%#{title}%’
这种写法是错误的,如果只是像
Select * from news where title like ‘%${title}%’
这样简单的将#换成$而不再java代码层面进行验证限制。就很容易出现sql注入问题,我们可以这样写
select * from news where tile like concat(‘%’,#{title}, ‘%’)
2.in 之后的多个参数
错误示例
Select * from news where id in (#{ids})
正确用法为使用foreach,而不是将#替换为$
<foreach collection="ids" item="item" open="("separatosr="," close=")">
#{ids}
</foreach>
order by 之后
这种场景应当在Java层面做映射,设置一个字段/表名数组,仅允许用户传入索引值。这样保证传入的字段或者表名都在白名单里面。需要注意的是在mybatis-generator自动生成的SQL语句中,order by使用的也是$,而like和in没有问题。