一、符号应用举例
// 在 select 标签中应用,# 用于示意占位符,把他独自作为某个值;而 $ 用于示意字符串拼接
<select id="selectUserByUserNameOrEmail" resultMap="BaseResultMap">
select * from #{tableName}
</select>
二、举例应用并辨别
1.select from #{tableName} 和 select from ${tableName}
①对于 #号来说,因为它示意占位符,他是作为值存在的,因而它理论传输的语句 select from?,而这种语句是须要预编译的。假如我当初传递参数为字符串 ’user’,语句就变成 select from ‘user’,这样的语句是无奈执行的。
②而对于 $ 号来说,select * from ${tableName},他是以字符串拼接的模式,因而他是可能执行的
③那这样来说,是不是意味着 $ 更好呢?其实并不是,咱们来看上面的语句
2.select from auth_user where username = #{userName} 和 select from auth_user where username = %{userName}
①从下面的例子咱们能够晓得 $ 是对字符串进行拼接再执行 SQL 语句的,假如咱们执行下面的语句就会产生一个问题,我怎么晓得输出的 userName 是不是失常的呢,假如他是好人呢?如输出 ”username’ or ‘1’= `1″ 语句就会变成
select * from auth_user where username = "username' or '1'= `1"
也就是咱们常说的 SQL 注入,这样会导致咱们所有的用户信息都会裸露进去!!!
三、日常应用
1. 仔细的同学可能发现了,第一个 SQL 语句须要的参数是咱们程序员已知的,而第二个 SQL 语句须要的参数是用户输出的。因而,咱们能够得出一个论断,个别 #用于用户输出值的中央、$ 用于程序员本人赋值的中央
四、区别
1.# 号示意占位符;$ 示意拼接字符串
2.# 号应用的是 PreparedStatement,他会进行预编译,能避免 SQL 注入;而 $ 应用的是 Statement
五、为什么预编译能避免 SQL 注入?
1. 解释:在应用占位符,或者说参数的时候,数据库曾经将 sql 指令编译过,那么查问的格局曾经订好了,也就是咱们说的我曾经明确你要做什么了,你要是将不非法的参数传进去,会有合法性检查,用户只须要提供参数给我,参数不会当成指令局部来执行,也就是预编译曾经把指令以及参数局部辨别开,参数局部不容许传指令进来
2. 了解:预编译的时候是先把这句话编译了,生成 sql 模板, 相当于生成了一个我提前晓得你要查名字了
,你把名字传给我,你当初想骗我,把字符串 ”username’ or ‘1’= `1″ 传进去,那么数据库去名字这一字段帮你找,发现没有这个人,天然也就无奈生成编译语句了