区别:
1. #{}是预编译处理(占位符,替换结果会增加单引号),${}是字符串替换。
2. Mybatis 在处理#{}时,会将 sql 中的#{}替换为?号,调用 PreparedStatement 的 set 方法来赋值;
Mybatis 在处理${}时,就是把${}替换成变量的值。
3. 使用#{}可以有效的防止 SQL 注入,提高系统安全性。
·4. 获取值方式的区别:${value},#{参数名}
注:表名作为变量时,必须使用${]
具体分析:
动态SQL是mybatis的强大特性之一,也是优于其他ORM框架的一个重要原因。在进行查询前会对sql语句进行动态解析。
mybatis提供了两种支持动态解析的语法:${}和#{}。
然而${}和#{}在预编译中的处理是不一样的。
如:
select * from user where name = #{name};
select * from user where name = ${name};
虽然执行结果都是:select * from user where name = 'zhangsan';,没有差别,但是在动态解析的流程是不相同的
#{}解析为一个JDBC预编译语句(prepared statement)的参数标记符
解析为:select * from user where name = ?。一个#{}为一个占位符?
而,${}仅仅为一个String替换,在此此阶段将会进行变量替换
假设参数为"zhangfei",则会解析为select * from user where name = "zhangfei"。 预编译之前就已经不包含变量name了。
所以,${}变量的替换阶段是在动态sql解析阶段,而#{}的变量替换是在 DBMS(数据库管理系统) 中
用法区别:
a. 能使用#{}就使用#{}
首先,性能高,相同的预编译sql可以重复利用
其次,因为${}在预编译之前变量就被替换了,存在SQL注入问题
如:select * from ${tableName} where name = #{name}
表名为user; delete user; -- (当然现实情况这个表名不合法,只是举例)
若用${},则会变成select * from user; delete user; -- where name = ?;,sql语句完全变了
b. 当传入的参数为表明时,只能使用${}
如:select * from ${tableName} where name = #{name}
表名为user
如果使用#{},会在两端加上单引号
select * from 'user' where name = #{name}
表名上有单引号,当然会报错了,,,记住这里不是sql里的反引号