乐趣区

MyBatis中和的区别

微信公众号:51 码农网
专业编程问答社区
www.51manong.com

1. 先看 #{}解析为一个 JDBC 预编译语句(prepared statement)的参数标记符, 把参数部分用占位符 ? 代替。动态解析为:

select * from t_user where username = ?;

而传入的参数将会经过 PreparedStatement 方法的强制类型检查和安全检查等处理,最后作为一个合法的字符串传入。

在 #{}预处理之后可以预防 SQL 注入传入 username 为 a‘or’1=1,使用 #{}, 经过 sql 动态解析和预编译, 会把单引号转义为’那么 sql 最终解析为:

select * from t_user where username = "a\' or \'1=1";

2. 再看 ${}这种方式只会做简单的字符串替换,在动态 SQL 解析阶段将会进行变量替换, 假如传递的参数为 51mn, 最终处理结果如下:

select * from t_user where username = '51mn' ;

${} 预编译之前就已经被替换, 有被注入的风险。如果传入的 username 为 a‘or’1=1, 那么使用 ${} 处理后直接替换字符串的 sql 就解析为:

select * from t_user where username = 'a' or '1=1' ;

所有的用户信息都会被查询出来了。

退出移动版