欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MyBatis 中 #{} 和 ${} 区别

程序员文章站 2022-07-14 11:10:09
...

MyBatis 中 #{} 和 ${} 区别

#{} 的理解:

#{} 是预编译处理,像传进来的数据会加个" "(#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号)。

  • #{} 将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号。如:order by #user_id#,如果传入的值是 111,那么解析成 SQL 时的值为order by " 111 ",如果传入的值是id,则解析成的 SQL 为order by " id "。
  • ${} 将传入的数据直接显示生成在 SQL 中。如:order by $ user_id $,如果传入的值是111,那么解析成SQL时的值为order by user_id, 如果传入的值是id,则解析成的 SQL 为order by id。
  • #{} 方式能够很大程度防止 SQL 注入。
  • ${} 方式无法防止 SQL 注入。

${} 的理解:

{} 就是字符串替换。直接替换掉占位符。$方式一般用于传入数据库对象,例如传入表名。

Mapper.xml中使用#{}表达式:

MyBatis 中 #{} 和 ${} 区别

使用 #{}后,打印SQL语句:

MyBatis 中 #{} 和 ${} 区别

Mapper.xml中使用${}表达式:

MyBatis 中 #{} 和 ${} 区别

使用 ${}后,打印SQL语句:

MyBatis 中 #{} 和 ${} 区别

举一个例子:

在下面的语句中,如果 name 的值为 EPEP,则两种方式无任何区别:

select * from user where name = #{name};
select * from user where name = ${name};

其解析之后的结果均为

select * from user where name = #{EPEP};

但是 #{} 和 ${} 在预编译中的处理是不一样的。#{} 在预处理时,会把参数部分用一个占位符 ? 代替,变成如下的 SQL语句:

select * from user where name = ?;

而 ${} 则只是简单的字符串替换,在动态解析阶段,该 SQL 语句会被解析成

select * from user where name = 'EPEP';

但,如果存在 SQL 注入呢?看下边的 SQL 语句:

select * from ${tableName} where name = #{name}

在这个例子中,如果表名为:

user; delete user; --

在动态解析后 SQL 语句如下:

select * from user; delete user; -- where name = ?;

– 之后的语句被注释掉,而原本查询用户的语句变成了查询所有用户信息+删除用户表的语句,会对数据库造成重大损伤,极大可能导致服务器宕机。

name = ?;


-- 之后的语句被注释掉,而原本查询用户的语句变成了查询所有用户信息+删除用户表的语句,会对数据库造成重大损伤,极大可能导致服务器宕机。

**但是**,表名用参数传递进来的时候,只能使用 ${} 。这也提醒我们在这种用法中要小心 SQL 注入的问题。
相关标签: SSM