暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Mybatis中#{}和${}区别

IT那活儿 2022-04-07
1013

点击上方“IT那活儿”,关注后了解更多内容,不管IT什么活儿,干就完了!!!

初探#{}和${}

Mybatis中#{}和${}是传递查询参数的两种方式,首先看下他们的使用方式,这里以查询姓名中包含字符“J”的数据列表为例。

现有一张User表,结构和数据如下:

定义Dao接口:

定义Mapper文件:

执行单元测试:

查看结果,两种方式都查询出了两条记录,都实现了需求。

SQL注入

#{}和${}虽然都能实现查询,但区别还是有的,最大区别是${}方式可能导致SQL注入问题

看个例子,把上面的查询条件改动下,在条件后加入' or 1=1 -- ,再分别看下结果。

修改查询条件:

查看执行结果,可以看到#{}方式查询结果为0条,${}方式查出了所有记录。

细思极恐啊,如果采用${}方式执行update或delete操作,那整张表数据都会受到影响。

#{}和${}区别

查看mysql执行log日志,拿到两种方式执行的sql语句如下:

对比发现,虽然两种方式查询条件传入的字符串一样,但是Mysql执行时生成的语句并不一样,${}是字符串替换,而#{}是预处理,预处理时会对特殊字符进行转义操作。

Mybatis在处理${}时,就是把${}值直接替换成变量值。而在处理#{}时,会对sql语句进行预处理,将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值。

因此,使用#{}可以有效的防止SQL注入,提高系统安全性。

应用场景

我们已经知道#{}可以有效的防止SQL注入,那为什么还要有${}方式呢?

既然存在,那肯定有用武之地,${}采用字符串拼接方式,还是举个例子来介绍它的使用场景。

例如,针对查询时表名不确定的情况,需要在查询时将表名通过参数传递进来,分别使用两种方式测试下。

Mapper文件如下:

执行单元测试:

查看结果,${}方式可以查询出结果,而#{}方式抛出异常,这种情况下只能选择${}方式查询。

总  结

#{}针对输入字符串进行了转义过滤处理,能够防止SQL注入,适用于给SQL语句的where条件传值的使用场景;

${}设计就是用于参与SQL的语法生成,适用于需要通过传递值来拼接SQL语句的场景。


本文作者:孙涛涛

本文来源:IT那活儿(上海新炬王翦团队)

文章转载自IT那活儿,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论