MyBatis 如何预防SQL注入------使用#{}与${}的区别

📅 2026/7/28 17:47:44
MyBatis 如何预防SQL注入------使用#{}与${}的区别
什么是SQL注入所谓SQL注入就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串最终达到欺骗服务器执行恶意的SQL命令。百度百科例如攻击者在密码栏上输入 or 1 1 #如果后台是通过SQL直接拼接用户输入来做查询的话攻击者就可以成功侵入了。如SELECT * FROM user WHERE uername or 1 1 # AND password 由于 1 1 是恒等式所以该 SQL 就相当于SELECT * FROM user所以后端需要对类似的攻击做好防备不能简单的使用字符串拼接来做SQL查询。#{}与${}的区别对于#{}select idgetUserById resultTypeUser parameterTypejava.lang.Integer SELECT uid, username FROM user WHERE uid #{uid} /selectMyBatis 的 #{} 底层其实是靠 JDBC 的 PreparedStatement 类实现 SQL 的预编译SELECT uid, username FROM user WHERE uid ?然后通过parameterType确定传入的参数类型将预编译好的 SQL中的占位符 替换成传入的参数。因为 SQL 注入只对编译过程起作用所以这样就可以很好地避免 SQL注入的问题了。而且在多次执行同一个SQL时能够提高效率。原因是SQL已编译好再次执行时无需再编译。对于${}select idgetUserById resultTypeUser parameterTypejava.lang.Integer SELECT uid, username FROM user WHERE uid ${uid} /select在MyBatis中${} 这样格式的参数会直接参与SQL编译从而不能避免注入攻击就好像前面 SQL 注入所提到的例子一样。但涉及到动态表名和列名时只能使用 ${} 这样的参数格式。因为使用 #{} 的话就好比使用 parameterType 的 setString() 方法插入字符串但这样做是会让参数带上单引号的。如总结在编写MyBatis的SQL时尽量采用#{}。除非有需要才使用${}但要注意做好过滤工作防止SQL注入攻击。#{}相当于JDBC中的PreparedStatement会帮我们预编译再替换其中的 ${}是直接输出变量的值然后拼接成 SQL 执行