MyBatis中#{ }和${ }都可以用来动态传递参数,补全SQL语句,但它们区别也很明显。
一、#{}
在SQL中相当于一个参数占位符“?”,用来补全预编译语句。它补全预编译语句时,可以理解为在此参数值两端加了单引号。举例如下,当需要动态的按id查询用户信息时。
@Select("select * from my_user where id = #{id}")
如果我们为id赋值为1,执行效果相当于下面的SQL。
select * from my_user where id = '1';
由于预编译SQL使用PreparedStatement
对象抽象预编译语句,之后使用也无需再次编译,而且能够防止注入式攻击,所以只要能够使用#{ }解决的地方,我们都应该使用#{ }。
二、${}
单纯的字符串拼接,拼接完成后才会对SQL进行编译、执行,所以性能较低,也无法复用。但是在有些#{ }无法胜任的地方,还是会需要${ }来完成。比如当SQL中数据库表名为参数时,如果使用#{ },如下所示。
@Select("select * from #{tableName}")
当我们为tableName赋值为"my_user"时,相当于执行以下SQL。
select * from 'my_user';
由于表名不能加单引号,所以语法错误。这时候就需要使用${ }来进行字符串拼接。
@Select("select * from ${tableName}")
为tableName赋值为"my_user"后,相当于执行以下SQL。
select * from my_user;