在使用mybatis的时候我们会使用到 # { } 和 $ { } 这两个符号来为sql语句传参数
而这两个 符号有什么区别呢?
#{ } :是预编译处理,是占位符。
${ }:是字符串替换,是拼接符,且存在安全问题。
日志分析:
我们通过打印日志进行观察:
使用#{}的情况:
使用${}的情况:
在这里我们可以观察到 使用#{}的时候是先使用? 进行占位,然后调用PreparedStatement来赋值。
而使用${}的时候是直接进行替换操作
实践场景区别:
因此我们得出经验的结论
当传值是Integer的时候,都可以使用
当传值为 String类型,只能使用#{ } ,因为直接替换的不会给加上 " ",而导致sql语句错误
当传值含有mysql的关键字,只能使用 ${ } ,因为另一种会误认为是字符串
// 1.传值是Integer的时候,都可以使用
<select id="getUserById" resultType="com.example.demo.entity.Userinfo">
select * from userinfo where id=#{id};
</select>
<select id="getUserById" resultType="com.example.demo.entity.Userinfo">
select * from userinfo where id=${id};
</select>
// 2.传值为 String类型,只能使用#{ }
<select id="getUserByName" resultType="com.example.demo.entity.Userinfo">
select * from userinfo where id=#{name};
</select>
// 3.当传值为关键字,只能使用 ${ }
<select id="getAllUserByOrder" resultType="com.example.demo.entity.Userinfo">
select * from userinfo order by ${key} ${arrange}};
</select>
注意sql注入问题:
使用${ } 传入的对象必须是可预期的,比如传入desc 或者asc
原因:会产生sql注入问题
案例:使用 ${ } 获取密码的时候,用户输入 ' or 1='1''
这时候 判断语句就会判定为正确,从而导致用户进入账户
结论:
能用#{} 的时候尽量用#{}
当要用到${}的时候(可以穷举的时候),要验证参数的合法性(比如使用if进行判断)!