1 、 理论区别
$与#的区别是很大的。#为占位符,而$为字符串拼接符。 字符串拼接是将参数值以硬编码的方式直接拼接到了SQL 语句中。字符串拼接就会引发 两个问题:SQL注入问题 与没有使用预编译所导致的执行效率低下问题。 占位符的引入,解决以上两个问题。
2、 应用场景
一般情况下,动态参数的值是由用户输入的,则不能使用拼接符$,因为有可能会出现SQL注入;若动态参数的值是由系统计算生成的,则可以使用拼接符$。但这样虽然不存在SQL 注入的风险,但仍存在执行效率问题。
3、SQL 注入
在MyBatis 中,使用#号占位符,则后台执行 SQL 使用的为 PreparedStatement,将会防止 SQL注入。而使用$符,则为字符串拼接,使用的为 Statement,将无法防止 SQL 注入。
例如,Mapper.xml中如下的 sql 语句:
select * from user where name = #{name};
动态解析为: select * from user where name = ?;
一个 #{ } 被解析为一个参数占位符 ? 。
而${ } 仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段将会进行变量替换。
例如,Mapper.xml中如下的 sql:
综上所得, ${ } 变量的替换阶段是在动态 SQL 解析阶段,而 #{ }变量的替换是在 DBMS 中。