#{}与${}的区别
# {}与${}的区别
默认情况下,使用#{}语法,MyBatis会产生PreparedStatement语句中,并且安全的设置PreparedStatement参数,这个过程中MyBatis会进行必要的安全检查和转义。
示例1:
执行SQL:Select * from user where name = #{name}
参数:name=>xin
解析后执行的SQL:Select * from user where name = ?
执行SQL:Select * from user where name = ${name}
参数:name:ke
解析后执行的SQL:Select * from user where name =ke
说明:
-
#
将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #{user_id},如果传入的值是 name , 那么解析成sql时的值为order by “name”, 如果传入的值是id,则解析成的sql为order by “id”. -
$
将传入的数据直接显示生成在sql中。如:order by ${user_id},如果传入的值是name, 那么解析成sql时的值为order by name, 如果传入的值是id,则解析成的sql为order by id.
综上所述,$ {}
方式会引发SQL注入的问题、同时也会影响SQL语句的预编译,所以从安全性和性能的角度出发,能使用#{}
的情况下就不要使用 ${}
。
${}
在什么情况下使用呢?
有时候可能需要直接插入一个不做任何修改的字符串到SQL语句中。这时候应该使用${}语法。
比如,动态SQL中的字段名,如:ORDER BY ${columnName}
<select id="queryMetaList" resultType="Map">
Select * from name where name = ${name} ORDER BY ${age}
</select>
由于${}
仅仅是简单的取值,所以以前sql注入的方法适用此处,如果我们order by语句后用了${}
,那么不做任何处理的时候是存在sql注入危险的。