Mybatis参数占位符#{}与${}区别
2021-03-03 本文已影响0人
DoubleFooker
《每天学点CRUD》 公众
今天的一天枯燥的复制粘贴,感觉工作没有了激情,俨然沦为工具人。但是好学的我还是发现了有意思的东西。
Mybatis应该是国内码农用的最频繁的框架,毕竟一套技术栈走天下。那么今天来讲讲参数绑定#{}
和${}
的区别。
#
与$
的区别
当你用${}
传递参数时,idea还会出现警告。提示可能存在sql注入漏洞。
没错,#{}
与${}
最大的区别就是${}存在sql注入风险。
下面这两种方式,如果入参name是个正常参数,那么结果是一致的。
select * from user where name = #{name};
select * from user where name = ${name};
Mybatis在动态解析sql时,会将#{}
参数替换为占位符,例如:
select * from user where name = ? ;
而${}仅仅是做字符串的替换,例如:
select * from user where name = 'Jay' ;
这时如果入参是不怀好意的字符串就可能导致SQL注入,例如:
入参为:Jay';delete from user,SQL就会解析成:
select * from user where name = 'Jay';delete from user ;
Mybatis是怎么实现的呢?
Mybatis是对JDBC封装的持久层框架,动态sql解析成BoundSql对象,使用#{}时解析成JDBC的PreparStatement预编译SQL,后面对于同一个SQL还能直接使用。
ONE MORE THING
如果#{}无法满足使用场景,必须得用${}那怎么办呀,例如动态传入表名查询。
select * from ${tableName} where `year` > '2021';
这种情况使用#{}解析的sql是错误的无法执行。
如果必须要使用${},那么只能在代码上做文章,确保执行sql的入参是安全的。