MyBatis中#{}和${}的区别
- #{} 是预编译处理,是占位符,${} 是字符串替换、是拼接符;
- MyBatis 在处理 #{} 时,会将 sql 中的 #{} 替换为 ?,调用 PreparedStatement 来赋值;
- MyBatis 在处理 ${} 时,是把 ${} 替换成变量的值,调用 Statement 来赋值;
- 使用 #{} 可以有效地防止 SQL 注入,提高系统安全性。
示例:
name = zhangsan;
password = 1or 1=1;
#{}
SELECT * FROM user WHERE name = #{name} and password = #{password};
将转为:
SELECT * FROM user WHERE name = 'zhangsan' AND password = '1 or 1=1';
${}
SELECT * FROM user WHERE name = ${name} AND password = ${password};
将转为:
SELECT * FROM user WHERE name = zhangsan AND password = 1 or 1=1;
注意:
- 像 order by 后使用 ${},如果使用 #{} 会导致转换的时候多了一对单引号,从而排序失败。
- like 则需要根据表达式的书写进行选择。
- in 后如果使用 ${} ,可以直接操作;如果是 #{} ,需要循环遍历来进行操作。
例:name like"%"#{name}"%"
Preparing: select * from bbs_brand WHERE namelike"%"?"%"and falg=? limit 0 , 10
Parameters: 莲(String), 1(Integer)
使用了占位符来占位,写成SQL就是: name like "%"'莲'"%"没有问题
例:name like '%${name}%'
Preparing:select count(0) from (select * from bbs_brand WHERE name like'%莲%' and falg=?) as total
Parameters: 1(Integer)
使用$进行字符串的拼接,直接把传入的值,拼接上去了,没有任何问题
例:name like concat(concat('%',#{username}),'%')
Preparing: select count(0) from (select *from bbs_brand WHERE name like concat(concat('%',?),'%') and falg=?) as total
Parameters: 莲(String), 1(Integer)
使用了cancat进行字符串的连接,同时使用了#进行占位
例:name like CONCAT('%','${name}','%')
Preparing: select count(0) from (select *from bbs_brand WHERE name like CONCAT('%','莲','%') and falg=?) as total
Parameters: 1(Integer)