Mybatis的mapper.xml中有两种方式可以对方法形参取值,#{}和${},这两个的区别用和应用场景有些区别。
本文简述区别
#{ }
#{ }解析SQL
脚本时,会使用PreparedStatement
执行SQL
语句,会将#{}作为占位符?,然后将形参取出赋值,可以有效防止SQL
注入
ps:
1 | <select id="one" resultType="com.example.pojo.Dept"> |
1 | # 最后?占位符会加上引号 |
${ }
${ }解析SQL脚本时,会直接将形参变量取出,然后拼接在SQL语句中,这里用的也是PreparedStatement
ps:
1 | <select id="one" resultType="com.example.pojo.Dept"> |
这时候就会存在一个问题,SQL注入
,传入参数为'' or 1=1
类似恒等式
1 | select * from dept where dept_id = '' or 1=1; |
在只有一个形参时{ }里面可以不用写对应的形参变量名,比如{xxx},但是建议相同
#{}方式是先用?代替参数将SQL语句进行预编译,然后再将参数中的内容替换进来,非法参数内容只会是一个参数,不会在为SQL命令的一部分,可以有效防止SQL注入
只能使用${}的场景
由于#{}会给参数内容加上引号,有些时候需要字段、表名的情况下,SQL会出现问题。
ps:
- 排序时字段有引号,排序失效
- 表名有引号,直接报错
所以这些情况下只能使用${}。