MyBatis中的赋值语句:#{}和${}的区别差异(常见面试题)

我们开始先总结他们的差异,后面再使用代码展示差异

1.0.#{}和${}的差异

(1)${}可能存在sql注入的安全问题

(2)${}是即时sql(参数直接拼接),不能进行缓存;#{}是预编译sql(参数通过替换占位符的方式),可以缓存

(3)${}拼接字符串参数时不带引号,而#{}拼接参数会带上引号

(4)在不能自带引号的场景下,只能使用${};比如实现排序功能等

1.1.差异的原因

下面我们通过一段代码,就可以知道它们产生差异的原因了。

(1)参数是否拼接

分别使用不同符号的进行赋值

我们可以看到,当使用#{}的时候,参数位置使用的是一个占位符,而${}则是直接把参数拼接在上面了。这是它们两处不一样的地方。

(2)有无引号

下面我们将参数的类型从Integer换成String

测试结果:

发现直接使用$传参会报错,原因就是它没有自动加上双引号或者单引号;如果我们自己加上:

运行结果也就没有报错了 

由此可见,${}就是可以自己是否带引号的,这点就是让它成为有sql注入的主要原因

(3)sql注入

在上面可以知道,${}可以自主选择带引号,因此,就可以进行sql拼接,也就存在被sql注入的风险。

比如下面的sql语句:

SELECT * from userinfo where username = ' ' or 1= '1'
//参数:' or 1='1

运行结果:

很明显sql执行成了,也就是说,确实是真真实实存在sql注入的风险。(但是一般都可以通过java代码来预防注入风险)

(4)即时sql和预编译sql

sql的执行流程:sql语法检验和解析、sql优化、sql执行

因为#{}的参数使用占位符,每次只需要替换占位符就可以,因此第一、二步可以缓存下来,每次只需要执行第三步即可,效率也就更快;因此称为:预编译sql。

而${}每次都是需要拼接参数,所以不能缓存,因此称为:即时sql

1.2.${}的作用

上面说的全是${}的缺点,那它还有用武之地吗?其实没有被淘汰,也就是还有作用的,作用场景也就是参数不能有引号的情况。

(1)对某个字段排序

对数据库中的数据进行排序,相信大家不陌生吧,我们还是先复习一下排序的sql语句

默认排升序:select * from 表名  order by 列名/表达式  

排降序:select * from 表名  order by 列名/表达式 desc

如果我们需要排降序的话,就需要传参,也就是将desc作为参数,但是在sql语句中,desc是没有引号的,但是#{}对字符串传参时,会自动加上引号,进而会导致sql错误,所以只能使用${}

  • 使用#{}时

结果已经很明显了。

  • 使用${}

但是这样也会存在sql注入的安全问题,所以就需要将参数设置成枚举类型这样的可选类型。并且如果表名和字段名作为参数时也必须使用${},原因就是它们不能有引号

(2)模糊查询

模糊查询虽然不是使用${}和#{},但是也需要介绍一下原因。

复习一下模糊查询:

select * from userinfo where username like ' %min% '

%min%就是一个模糊的概念,两边是需要加上引号的。但是%min%是一个字符串,min就是我们需要的参数,不能有任何字符串。

  • #{}

报错

  • 使用${}

因为是${},所以依旧存在sql注入的风险,所以模糊查询不会使用${},而是使用内置函数

  • 使用内置函数
   @Select("select * from userinfo where username like concat('%',#{key},'%') ")
   List<UserInfo> queryUserInfoBylike(String key);


以上就是本文的全部内容。

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码小娥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值