mybatis中的#{}和${}的区别

1. 取值范围不同

MyBatis既可以获取执行SQL时插入的请求参数,也可以从主配置文件加载的配置文件中获取配置参数。
#{}只能获取请求参数的值,无法获取配置参数。
${}在MyBatis初始化时能获取配置参数,如果没有,执行时再获取请求参数。

2. 处理方式不同

#{}

  1. 如果SQL中只有#{}或者可以被配置参数替换的${},那么在初始化时#{}就被解析成了占位符?
  2. 如果SQL中有动态标签(例如ifwhere),或者无法被配置参数替换的${},那么#{}在执行SQL时才会被替换成占位符?#{}的值是执行SQL时通过JDBC的Statement根据占位符进行设置。

${}

  1. 如果可以被配置参数替换,则在初始化时已被配置参数替换,否则在执行SQL时使用请求参数替换。
  2. ${}的值使用参数值直接替换,不做任何特殊处理。

3. 安全性不同

#{}能够很大程度防止SQL注入。
${}无法防止SQL注入。

所以,能用#{}的就别用${}
${}方式一般用于传入数据库对象,例如传入表名,排序字段等。

4. 测试验证

以下是自己做过的一些测试验证场景:

测试场景一:
${}是否能够获取配置文件中的参数?如果能获取配置参数,那么是初始化时替换${}还是执行时替换${}

测试结果一:
${}在MyBatis初始化时,获取MyBatis主配置文件中加载的配置参数进行替换。

  1. SQL中只有${}${}被替换成配置参数,在所有${}都被替换的情况下,生成的是静态SQL对象。
  2. SQL中只有${}#{}${}被替换成配置参数,在所有${}都被替换的情况下,#{}会被替换成?,且生成静态SQL对象。
  3. SQL中存在${}和动态标签,${}无论在动态标签内或者外,${}都被替换成配置参数,生成动态SQL对象。
  4. SQL中存在${}#{}和动态标签,${}被替换成配置参数,#{}没有被替换成?,生成动态SQL对象。

测试结论一:
在MyBatis初始化阶段,解析XML配置文件的过程中,会对${propertyName}占位符做解析,如果能够在配置参数中获取到key=propertyName的值,那么就会使用配置参数值替换${propertyName},否则保留。所以在xxxMapper.xml中使用${propertyName}获取参数时,需要考虑是获取配置文件中的值,还是获取SQL执行时传入的请求参数值。这可能会出现意想不到的结果。

测试场景二:
如果SQL中有动态标签或者${}符号,且${}不会被配置参数替换时,SQL中的#{}在初始化时替换成?,还是在执行时被替换成?

测试结果二:
在MyBatis初始化过程中的测试结果:

  1. SQL中仅有#{}#{}被替换成?
  2. SQL中有#{}${}#{}没有被替换成?
  3. SQL中有#{}和动态标签,#{}无论在动态标签内还是外,都没有被替换成?
  4. SQL中有#{}${}、动态标签,#{}没有被替换成?

在SQL执行过程中的测试结果:

  1. SQL中仅有#{}#{}在初始化阶段就已被替换成了?
  2. SQL中有#{}${}#{}被替换成?${}被替换成参数值。
  3. SQL中有#{}和动态标签,#{}被替换成?,动态标签根据参数被解析。
  4. SQL中有#{}${}和动态标签,#{}被替换成?${}被替换成参数值,动态标签根据参数被解析。
  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值