MyBatis参数为0时跟空字符串''判断相等的分析以及解决办法

  • 起因
    之前在一个Mapper文件中写了这样一个if标签,结果当参数为0时不论如何if标签的判断都是false,打印sql也发现当参数为0时这个条件会不起作用,因此查看了一下MyBatis中相关的源码,if标签如下:
        <if test="backCarType != null and backCarType != ''">
			and m.back_car = #{backCarType,jdbcType=BIT}
		</if>
  • MyBatis 创建BoundSql的过程
    上文提到了MappedStatement这个类,这个类中有一个getBoundSql()方法,现在来跟踪一下这个方法:
  - MappedStatement.getBoundSql(Object parameterObject) 
  public BoundSql getBoundSql(Object parameterObject) {
   
    BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
    List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
    if (parameterMappings == null || parameterMappings.isEmpty()) {
   
      boundSql = new BoundSql(configuration, boundSql.getSql(), parameterMap.getParameterMappings(), parameterObject);
    }

    // check for nested result maps in parameter mappings (issue #30)
    for (ParameterMapping pm : boundSql.getParameterMappings()) {
   
      String rmId = pm.getResultMapId();
      if (rmId != null) {
   
        ResultMap rm = configuration.getResultMap(rmId);
        if (rm != null) {
   
          hasNestedResultMaps |= rm.hasNestedResultMaps();
        }
      }
    }

    return boundSql;
  }

  - DynamicSqlSource.getBoundSql(Object parameterObject)
  public BoundSql getBoundSql(Object parameterObject) {
   
    DynamicContext context = new DynamicContext(configuration, parameterObject);
    rootSqlNode.apply(context);
    SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);
    Class<?> parameterType = parameterObject == null ? Object.class : parameterObject.getClass();
    SqlSource sqlSource = sqlSourceParser.parse(context.getSql(), parameterType, context.getBindings());
    BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
    context.getBindings().forEach(boundSql::setAdditionalParameter);
    return boundSql;
  }

重点关注这个rootSqlNode,因为它就是解析我们写在mapper文件中的各种标签,比如if、choose、foreach等,接下来看一下是怎么解析if标签的:

public class IfSqlNode implements SqlNode {
   
  private final ExpressionEvaluator evaluator;
  private final String test;
  private final SqlNode contents;

  public IfSqlNode(SqlNode contents, String test) {
   
    this.test = test;
    this.contents = contents;
    this.evaluator = new ExpressionEvaluator();
  }

  @Override
  public boolean apply(DynamicContext context) {
   
    if (evaluator.evaluateBoolean
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值