#{}与${}的区别
写在前面:欢迎来到「发奋的小张」的博客。我是小张,一名普通的在校大学生。在学习之余,用博客来记录我学习过程中的点点滴滴,也希望我的博客能够更给同样热爱学习热爱技术的你们带来收获!希望大家多多关照,我们一起成长一起进步。也希望大家多多支持我鸭,喜欢我就给我一个关注吧!
首先,我们都知道。 #{}与 ${}都可以用来对SQL语句传值。但默认情况下,我们都会采用第一种,使用#{}来传值。那么为什么不建议使用 ${} 呢。明明我用 ${}照样可以执行SQL啊。
这里我们要说一下,#{} 与 ${} 传参的区别:
使用 #{} 传入参数时,sql语句在解析过程中会加上 “”。
例如:
select * from user where name = #{name}
传入值为 name = 小张
此时在打印输出一下SQL语句:
select * from table where name = ‘小张'
就是会当成字符串来解析。
而如果是使用${}传入参数时,输出的值就是当前值,不会附加" "。
还是以上面那个例子为例吧!
select * from user where name = ${name}
传入值为 name = ‘小张’
此时在打印输出一下SQL语句:
select * from user where name = '小张'
虽然都可以执行,也看不出什么区别。那么,我下面在举一个例子吧!
假如我现在做一个用户名密码的登录验证,那么我可以这样写SQL语句:
select *
from user
where username = ${username} and password = ${password}
此时,我给username和password分别传入如下的值:
username = '1' or '1'='1' ;
password = '1' or '1'='1';
那么,接下来将发生不得了的事情了。
此时打印输出的SQL就是如下语句:
select *
from user
where username = '1' or '1'='1' and password = '1' or '1'='1'
这条语句等同于==>select * from user
相信大家都明白这条语句是什么意思吧!
此时,这个登录验证已经无效了,无论怎么查,只要数据库有数据,都会成功!
这样一对比,我们就知道了为什么使用#{}而尽量避免${}了。相比于 $ {} 的好处是比较明显对的吧。 #{}传参能防止sql注入,如果你传入的参数为 单引号’,那么如果使用${},这种方式 那么是会报错的。
当然,${}也不是完全没用的!
另外一种场景,如果你要做动态的排序,比如 order by column,这个时候务必要用${},因为如果你使用了#{},那么打印出来的将会是
select * from user order by 'name'
,这样是没用!
最后来一个小结吧!
小结:
1)#{}是预编译处理,$ {}是字符串替换。
2)MyBatis在处理 #{} 时,会将SQL中的#{}替换为?号,同时会使用PreparedStatement的set()方法来赋值;MyBatis在处理 $ { } 时,就是把 ${ } 替换成变量的值,因此会造成SQL语句的安全问题!
3)使用 #{} 可以有效的防止SQL注入,提高系统安全性。