动态传输的标识:
#{} :表示从接口声明的方法参数中获取参数,并设置到此sql语句当中。
${}:表示从接口声明的方法参数中获取参数,并设置到此sql语句当中。
例如:
这么一个mapper层的接口方法:
执行的test,如下:
如果在mapper.xml文件中使用#{}:
会运行报错:
如果在mapper.xml中使用${}:
那么可以正常的得到查询结果:
从这个例子中,我们可以看到:如果使用的是#{},那么会给替换的值加上单引号,这样的话拼接的sql语法就错了,就会导致查询错误。
- 当替换SQL的信息为非系统(Mysql)关键字的时候,一定要使用#{}(这样可以预防SQL注入,因为如果有人恶意输入系统关键字的话,比如删库什么的,#{}会在上面加上引号,让其sql语法错误失效)
- 当替换的SQL为系统(Mysql)关键字的时候,一定要使用${};
在模糊查询中也应该使用${},道理也是#{}的话会给输入的参数加上一个单引号导致sql语法错误。
![在这里插入图片描述](https://img-blog.csdnimg.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等等可以将其手动排除掉。
- 方法二:使用系统提供的参数来进行参数拼接(第二种方法仅适用于模糊查询)
利用mysql中的concat
使用#{}可以防止sql注入的问题。