MyBatis #{}和${}的区别

2022年4月1日 100点热度 0人点赞 0条评论

#{} 与 ${} 区别

能使用 #{} 的时候尽量使用 #{}, 不使用 ${}.

#{} 相当于 JDBC 中的 preparedstatement(预编译), ${} 是直接使用里面的值进行拼接, 如果解释预编译和直接拼接, 我想可以这么理解预编译: 比如将一个 #{name} 传进来, 预编译是先将 SQL 语句编译成为模板, 也就是我知道你要干什么, 假设这个 SQL 是要查询名字为 xxx 的学生信息, 那无论这个 xxx 里面是什么信息, 我都只会去根据名字这一列查询, 里面无论写的是什么, 都只会当做一个字符串, 这个类型在预编译的时候已经定义好了.

${} 就不一样, 是将语句拼接之后才确定查询条件/类型的, 那么就会有被注入的可能性, 有些人故意将名字设置为删除条件, 这时候 SQL 就变成删除操作了.

所以我们一般类似模糊查询都是用 #{} 拼接.

select id,name,age,score from student where name like '%' #{name} '%'

但是对于 ORDER BY 我们是用不了 #{} 的, 因为用了这个就会被自动转换成字符串, 自动加引号, 这样语句就不生效了.

select id,name,age,score from student order by #{column}
select * from table order by 'column'

那我们需要怎么处理呢? 我们只能使用 ${}, MyBatis 不会修改或转义字符串. 这样是不安全的, 会导致潜在的 SQL 注入攻击, 我们需要自己限制, 不允许用户输入这些字段, 或者通常自行转义并检查, 所以这必须过滤输入的内容.

原文: https://blog.51cto.com/u_13604316/2729950

底层原理

MyBatis 自定义的占位符 #{} 最后被替换成 JDBC 的占位符 ?. 所以, 其实可以总结一下, 其实所有的 ORM 框架, 底层的原理都是 JDBC 的标准. 所以不管是 Mybatis 的占位符, 还是 JPA 中的占位符, 最终的执行流程都是解析成 ? 这个占位符, 别问为什么, 问这就是标准.

链接:https://juejin.cn/post/7012560302092861476

rainbow

没什么大用的码农; 贴图怪; bug制造者; 只会电脑开关机的开发;

文章评论