mybatis中#{}和${}的区别以及SQL注入问题

动态传输的标识:

#{} :表示从接口声明的方法参数中获取参数,并设置到此sql语句当中。

${}:表示从接口声明的方法参数中获取参数,并设置到此sql语句当中。

例如: 这么一个mapper层的接口方法: 执行的test,如下:

如果在mapper.xml文件中使用#{}: 会运行报错: 如果在mapper.xml中使用${}: 那么可以正常的得到查询结果: 从这个例子中,我们可以看到:如果使用的是#{},那么会给替换的值加上单引号,这样的话拼接的sql语法就错了,就会导致查询错误。

  1. 当替换SQL的信息为非系统(Mysql)关键字的时候,一定要使用#{}(这样可以预防SQL注入,因为如果有人恶意输入系统关键字的话,比如删库什么的,#{}会在上面加上引号,让其sql语法错误失效)
  2. 当替换的SQL为系统(Mysql)关键字的时候,一定要使用${};

在模糊查询中也应该使用${},道理也是#{}的话会给输入的参数加上一个单引号导致sql语法错误。

![在这里插入图片描述](https://img-blog.img.cn/259fd269bc1e4e988c00e0e86a5b6fe8.png

SQL注入问题

当使用${}的时候,会带来一个很严重的安全问题:sql注入问题 sql注入问题:使用一个特殊的sql查询了一个本来不应该查询到的内容,或者说做了一个本来不应该做的事。 举一个SQL注入问题的例子(拿一个模糊查询来举例): mapper: mapper.xml: 输入参数之前的sql语句为:

select * from userinfo where username like %${username}%

如果说输入这么一个参数:

%;delete from userinfo where username=%

那么拼接之后,就会形成一个(两个)新的sql语句:

select * from userinfo where username like %%;
delete from userinfo where username=%%

这样的话就很容易导致很严重的问题,删表。

如何解决SQL注入问题

1.方法一: Mapper类: 因为mapper类只有开发人员才会调用,无论黑客还是什么他们只会到达controller层,所以可以手动的排查掉sql注入的关键字,比如:‘/or/and等等可以将其手动排除掉。

  1. 方法二:使用系统提供的参数来进行参数拼接(第二种方法仅适用于模糊查询) 利用mysql中的concat 使用#{}可以防止sql注入的问题。
经验分享 程序员 微信小程序 职场和发展