前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >一个${}引发的惨案【MyBatis】

一个${}引发的惨案【MyBatis】

作者头像
林老师带你学编程
发布2021-03-02 16:25:51
9710
发布2021-03-02 16:25:51
举报
文章被收录于专栏:强仔仔强仔仔

想必大家在MyBatis开发过程中,对#{}和{}符号很熟悉吧,很多面试官都很喜欢问#{}和{}之间的区别,那它们到底有什么区别呢?

一、MySQL预编译

在开始介绍#{}和${}之前,我们先来讲讲MySQL预编译的含义。

当客户端发送一条SQL语句给服务器后,服务器总是需要校验SQL语句的语法格式是否正确,然后把SQL语句编译成可执行的函数,最后才是执行SQL语句。其中校验语法,和编译所花的时间可能比执行SQL语句花的时间还要多。

如果我们需要执行多次Insert语句,但只是每次插入的值不同,MySQL服务器也是需要每次都去校验SQL语句的语法格式,以及编译,这就浪费了太多的时间。如果使用预编译功能,那么只对SQL语句进行一次语法校验和编译,效率会更高。

二、MyBatis执行过程

动态 SQL 是 MyBatis 的主要特性之一,在 Mapper 中定义的参数传到 xml 中之后,在查询之前 MyBatis 会对其进行动态解析。

MyBatis 为我们提供了两种支持动态 SQL 的语法:#{} 以及 ${},下面我们具体来介绍一下他们之间的区别。

三、#{} 和 ${}

写过MyBatis代码的人都知道,#{} 和 ${}都是作为SQL语句的占位符,来映射SQL需要的实际参数。

#{} 和 {}最大的区别在于:预编译处理方式不一样,#{} 在预处理时,会把参数部分用一个占位符 ? 代替,而{}在预处理会直接把参数和原本SQL拼接到一起。

预编译结束之后,MyBatis会执行动态解析,解析SQL并发送给MySQL执行,这个时候对于${}而言,此时的SQL就是一条完整可执行的SQL,而对#{} 而言,此时的SQL是带有?占位符的SQL,MySQL会进行进一步的处理。

这也就是为什么我们都推荐使用#{} ,尽量少使用 {}的原因,因为#{}可以解决SQL注入的问题,{}不行。

四、实例讲解

在下面的查询语句中,如果 orderId 的值为 202011081153,则两种方式无任何区别:

代码语言:javascript
复制
select * from order where orderId = #{orderId};
select * from order where orderId = ${orderId};

其解析之后的结果均为

代码语言:javascript
复制
select * from order where orderId = 202011081153;

但是 #{} 和 ${} 在预编译中的处理是不一样的。

#{} 在预处理时,会把参数部分用一个占位符 ? 代替,变成如下的 SQL 语句:

代码语言:javascript
复制
select * from order where orderId = ?;

而 ${} 则只是简单的字符串替换,在动态解析阶段,该 SQL 语句会被解析成

代码语言:javascript
复制
select * from order where orderId = 202011081153;

以上,#{} 的参数替换是发生在 DBMS 中,而 ${} 则发生在动态解析过程中。

那么,在使用过程中我们应该使用哪种方式呢? 答案是:优先使用 #{}。因为 ${} 会导致 SQL 注入的问题。

再看下面的例子:

代码语言:javascript
复制
select * from ${tableName} where name = #{name}

在这个例子中,如果表名为

代码语言:javascript
复制
 order; delete  order; --

则动态解析之后 SQL 如下:

代码语言:javascript
复制
select * from order; delete order; -- where id = ?;

--之后的语句被注释掉,而原本查询用户的语句变成了查询所有订单信息+删除订单表的语句,会对数据库造成重大损伤,极大可能导致服务器宕机。

但是表名用参数传递进来的时候,只能使用 ${} 。这也提醒我们在这种用法中要小心sql注入的问题。

五、总结

介绍到这边,想必童靴们现在肯定都知道它们之间的区别了,我们在日常写SQL的时候,尽可能采用#{},如果非要使用${},一定要做好参数校验,防止出现SQL注入。

-----------------------

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-02-09 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档