Mybatis05__#和$的区别
Mybatis获取参数有两种方式,#{}和${},那么这两种取值的方式有什么不同
#{属性名}:对应的是PrepareStatement(预编译对象),可以使用通配符操作SQL,不会有SQL注入的现象,它可以自动加单引号.
${属性名}:对应的是Statement,必须使用字符串拼接的方式来操作SQL,有SQL注入的风险,不安全.
1、比如使用${}取值的时候,例如下面SQL语句会有SQL注入现象
1 | SELECT * FROM employee WHERE EMPLOYEE_AGE=${employeeAge} AND EMPLOYEE_ID=${employeeId} |
如果我们传入一个employeeAge= 23 or 1=1,那么使用${}的方式取值的话,SQL语句就会变成这样
1 | SELECT * FROM employee WHERE EMPLOYEE_AGE= 23 OR 1 = 1 AND EMPLOYEE_ID= 1 |
这个时候就是SQL注入了.一般情况下我们都使用#{}的取值方式,但是由于只有参数的位置才支持预编译,如果某一些场景下我们也是可以使用${}的方式
例如模糊查询和批量删除,以及不是参数的位置传递动态值等.
2、比如SELECT * FROM employee 如果我想把表名employee动态传入的话,就必须使用${}的形式,因为表名这个位置不是参数的位置,它不支持预编译,只能通过${}的形式来取值.
1 2 3 | // EmployeeMapper接口 @MapKey ( "EMPLOYEE_ID" ) public abstract List<Employee> queryEmployeeByEmployeeId(Map<String,Object> map); |
1 2 3 4 | // 动态传入表名,必须使用${}的方式取值 <select id= "queryEmployeeByEmployeeId" resultType= "com.mybatis.entity.Employee" > SELECT * FROM ${tableName} </select> |
1 2 3 4 5 6 7 8 | // 测试结果 [ Employee{employeeId= 1 , employeeName= '张三' , employeePassword= '123' , employeeAge= '23' , departmentId= 1 }, Employee{employeeId= 2 , employeeName= '李四' , employeePassword= '456' , employeeAge= '23' , departmentId= 2 }, Employee{employeeId= 3 , employeeName= '王五' , employeePassword= '789' , employeeAge= '25' , departmentId= 3 }, Employee{employeeId= 4 , employeeName= '赵六' , employeePassword= '1123' , employeeAge= '26' , departmentId= 4 }, Employee{employeeId= 5 , employeeName= '田七' , employeePassword= '123579' , employeeAge= '27' , departmentId= 1 } ] |
如果使用#{}来取值,便会报错,因为表名的位置不是参数的位置,预编译是不能在表名的位置设置参数的
1 2 3 | <select id= "queryEmployeeByEmployeeId" resultType= "com.mybatis.entity.Employee" > SELECT * FROM #{tableName} </select> |
1 2 3 4 5 | ### The error may involve defaultParameterMap ### The error occurred while setting parameters ### SQL: SELECT * FROM ? ### Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' employee '' at line 1 |
3、模糊查询的时候可以使用 '%${value}%' 来取值( "%"#{employeeName}"%" )
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?