#{}
#{}是一种占位符的方式把参数部分用占位符?代替。
动态解析为:
解析前:select * from user where name = #{name}
解析后:select * from user where name = ‘姓名’
而传入的参数将会经过PreparedStatement方法的强制类型检查和安全检查等处理,最后作为一个合法的字符串传入。
${}
${}是一种字符串拼接的方式。
解析前:select * from user where name = ${name} 解析后:select * from user
where name = 姓名
这样在预编译之前的sql语句已经不包含变量了,因此可以看出${} 变量的替换阶段是在动态SQL解析阶段。
区别
(1)、是否预防SQL注入
以上不同的处理方式可以看出,#{}预处理之后可以预防SQL注入,而传入的参数将会经过PreparedStatement方法的强制类型检查和安全检查等处理,最后作为一个合法的字符串传入;而${}在预编译之前就已经被替换,有被注入的风险。
(2)、性能处理方面
因为预编译语句对象可以重复利用,把一个sql预编译后产生的PreparedStatement对象缓存下来,下次对于同一个sql,可以直接使用缓存的PreparedStatement对象,mybatis默认情况下,对所有的sql进行预编译,这样的话#{}的处理方式性能会相对高些。
总结
- 能使用#{},就使用#{},一般情况下不仅效率高而且防止sql注入。
- 表名、order by的排序字段作为变量时,使用${}。
- #不需要关注数据类型,mybatis实现自动数据类型转换;$不做数据类型转换,需要自行判断数据类型。
- #是预编译的方式,$是直接拼接。