一个 ${}引发的惨案
#{} 和 {}最大的区别在于:预编译处理方式不一样,#{} 在预处理时,会把参数部分用一个占位符 ? 代替,而{}在预处理会直接把参数和原本 SQL 拼接到一起。
预编译结束之后,MyBatis 会执行动态解析,解析 SQL 并发送给 MySQL 执行,这个时候对于 ${}而言,此时的 SQL 就是一条完整可执行的 SQL,而对 #{} 而言,此时的 SQL 是带有?占位符的 SQL,MySQL 会进行进一步的处理。
这也就是为什么我们都推荐使用 #{} ,尽量少使用 {}的原因,因为#{}可以解决SQL注入的问题,{}不行。
四、实例讲解
在下面的查询语句中,如果 orderId 的值为 202011081153,则两种方式无任何区别:
select * from order where orderId = #{orderId};
select * from order where orderId = ${orderId};
其解析之后的结果均为
select * from order where orderId = 202011081153;
但是 #{} 和 ${} 在预编译中的处理是不一样的。
#{} 在预处理时,会把参数部分用一个占位符 ? 代替,变成如下的 SQL 语句:
select * from order where orderId = ?;
而 ${} 则只是简单的字符串替换,在动态解析阶段,该 SQL 语句会被解析成
select * from order where orderId = 202011081153;
以上,#{} 的参数替换是发生在 DBMS 中,而 ${} 则发生在动态解析过程中。
那么,在使用过程中我们应该使用哪种方式呢?
答案是:优先使用 #{}。因为 ${} 会导致 SQL 注入的问题。
再看下面的例子:
select * from ${tableName} 《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》无偿开源 威信搜索公众号【编程进阶路】 where name = #{name}
在这个例子中,如果表名为
order; delete order; --
则动态解析之后 SQL 如下:
评论