面试问题:持久层框架Mybatis中#{}与${}的区别

#{}与${}的区别

写在前面:欢迎来到「发奋的小张」的博客。我是小张,一名普通的在校大学生。在学习之余,用博客来记录我学习过程中的点点滴滴,也希望我的博客能够更给同样热爱学习热爱技术的你们带来收获!希望大家多多关照,我们一起成长一起进步。也希望大家多多支持我鸭,喜欢我就给我一个关注吧!

在这里插入图片描述

首先,我们都知道。 #{} ${}都可以用来对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注入,提高系统安全性

猜你喜欢

转载自blog.csdn.net/qq_43431171/article/details/106730237