在开发时使用到mybatis框架,会看到xml文件中有#{},也有${},那么它们之间有什么区别呢?本文就来详细的介绍一下它们之间的区别。
通俗的讲,#{}
相当于对数据加上双引号,${}
相当于直接显示数据。
Mybatis在处理
#{}
时,会将sql中的#{}
替换为?号,调用PreparedStatement的set方法来赋值;
Mybatis在处理${}
时,就是把${}
替换成变量的值,相当于字符串拼接
例如传入字符串var="id"
#{}
将传入的数据都当成一个字符串,会对自动传入的数据加引号:
select #{var} from user;
会被解析成:
select 'id' from user;
然后放到数据库去查询,它的查询结果为:
${}
将传入的数据都当成一个字符串,会对自动传入的数据加引号。
select ${var} from user;
会被解析成:
select id from user;
然后放到数据库去查询,它的查询结果为:
因此
#{}
方式适合用于传入查询条件
${}
方式一般用于传入数据库对象,例如传入表名、列名。一般在项目中我们要根据不同的业务场景可能需要去查询不同的列,或是不同的表,就可以用${}。
重点:#{}
方式能够很大程度防止sql注入,${}
方式无法防止Sql注入。
比如我要查询用户名为qqq的密码,通过上面的解析我们知道,使用#{}
的话需这样传值userName = “qqq
”;如果使用${}
的话需要这么传 userName = “'qqq'
”。因为如果你使用${}
时userName = "qqq
"的解析出来是qqq。放到数据库查询是会报错的,如下:
然后使用userName = "'qqq'
"解析出来是'qqq'
,查询如下:
这是正常的。
SQL注入的重点来了,本来我们查询条件限制了只查用户qqq的密码,但是这个时候如果别有用心的人把把查询条件userName的值输入为"'qqq' or 1=1
",这个时候的sql如下:
这个时候是不是所有用户的密码都查出来了。因此${}
是会有sql注入的风险的,很少会用到它。
如果使用#{}
的话,sql会是这样的:
可以有效防止sql注入。