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
中使用#{}
表达式:
使用 #{}
后,打印SQL语句:
在Mapper.xml
中使用${}
表达式:
使用 ${}
后,打印SQL语句:
举一个例子:
在下面的语句中,如果 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 注入的问题。
上一篇: kafka--基础知识点--14--kafka部署
下一篇: 数据类型扩展及面试题讲解
推荐阅读
-
mssql和sqlite中关于if not exists 的写法
-
Oracle SQL中实现indexOf和lastIndexOf功能的思路及代码
-
oracle存储过程中return和exit区别概述及测试
-
Laravel 中获取上一篇和下一篇数据
-
详解MySQL中DROP,TRUNCATE 和DELETE的区别实现mysql从零开始
-
ms sql server中实现的unix时间戳函数(含生成和格式化,可以和mysql兼容)
-
PHP和MySql中32位和64位的整形范围是多少
-
SQL中distinct 和 row_number() over() 的区别及用法
-
Python中的anydbm模版和shelve模版使用指南
-
C#中38个常用运算符的优先级的划分和理解