经验积累-Mybatis-${}占位符和#{}占位符区别

区别的表象

Mybatis占位符$和#,对大多数使用者来说,最直接的区别是: $占位符直接替换真实的值,无法避免SQL注入的漏洞. #占位符是在preparestatement的时候,使用占位符替换真实的值,可以避免SQL注入的漏洞. 因此,大多数的情况下,建议使用的是#占位符.

$占位符只是替换

$占位符的SQL,会创建DynamicSqlSource对象, DynamicSqlSource对象的变量替换,使用的是直接替换逻辑.
在做占位符替换的时候,会走TextSqlNode的handleToken方法:
    @Override
    public String handleToken(String content) {
      Object parameter = context.getBindings().get("_parameter");
      if (parameter == null) {
        context.getBindings().put("value", null);
      } else if (SimpleTypeRegistry.isSimpleType(parameter.getClass())) {
        context.getBindings().put("value", parameter);
      }
      Object value = OgnlCache.getValue(content, context.getBindings());
      String srtValue = (value == null ? "" : String.valueOf(value)); // issue #274 return "" instead of "null"
      checkInjection(srtValue);
      return srtValue;
    }

#占位符替换为?留给Preparestatement.

#占位符的SQL,会创建RawSqlSource对象.RawSqlSource对象的变量替换,使用的是preparestatement变量?替换逻辑.
在做占位符替换的时候,走ParameterMappingTokenHandler类的handleToken方法:
    @Override
    public String handleToken(String content) {
      parameterMappings.add(buildParameterMapping(content));
      return "?";
    }

原因解释(上源代码)

XMLLanguageDriver.java类
  @Override
  public SqlSource createSqlSource(Configuration configuration, String script, Class<?> parameterType) {
    // issue #3
    if (script.startsWith("<script>")) {
      XPathParser parser = new XPathParser(script, false, configuration.getVariables(), new XMLMapperEntityResolver());
      return createSqlSource(configuration, parser.evalNode("/script"), parameterType);
    } else {
      // issue #127
      script = PropertyParser.parse(script, configuration.getVariables());
      TextSqlNode textSqlNode = new TextSqlNode(script);
      if (textSqlNode.isDynamic()) {
        return new DynamicSqlSource(configuration, textSqlNode);
      } else {
        return new RawSqlSource(configuration, script, parameterType);
      }
    }
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值