mybatis源码-mapper文件中if语法分析

之前仿照mybatis写了一个sql语句与代码解耦的工具类,最一开始的设想是,应用程序能加载xml文件中的sql语句,并能对sql语句的形参赋值,完成sql的正确执行即可,但是这样不具有扩展性。

回想sql语句与代码耦合的场景,会有通过分支判断进行sql拼接的情况,所以今天又把mybatis的代码扒拉了一番,学学人家的if语法怎么实现正确解析的。

前提;自己搭好mybatis源代码环境(源码地址:GitHub - mybatis/mybatis-3: MyBatis SQL mapper framework for Java   下载下来导入idea即可)

一番debug进入org.apache.ibatis.scripting.xmltags.IfSqlNode.java 的apply 方法

@Override
  public boolean apply(DynamicContext context) {
    if (evaluator.evaluateBoolean(test, context.getBindings())) {
      contents.apply(context);
      return true;
    }
    return false;
  }

再进入org.apache.ibatis.scripting.xmltags.ExpressionEvaluator.java 的evaluateBoolean方法

public boolean evaluateBoolean(String expression, Object parameterObject) {
    Object value = OgnlCache.getValue(expression, parameterObject);
    if (value instanceof Boolean) {
      return (Boolean) value;
    }
    if (value instanceof Number) {
      return new BigDecimal(String.valueOf(value)).compareTo(BigDecimal.ZERO) != 0;
    }
    return value != null;
  }

重点要来了,进入org.apache.ibatis.scripting.xmltags.OgnlCache.java 的getValue 方法

public static Object getValue(String expression, Object root) {
    try {
      Map context = Ognl.createDefaultContext(root, MEMBER_ACCESS, CLASS_RESOLVER, null);
      return Ognl.getValue(parseExpression(expression), context, root);
    } catch (OgnlException e) {
      throw new BuilderException("Error evaluating expression '" + expression + "'. Cause: " + e, e);
    }
  }

附其中调用的 parseExpression方法内容:

private static Object parseExpression(String expression) throws OgnlException {
    Object node = expressionCache.get(expression);
    if (node == null) {
      node = Ognl.parseExpression(expression);
      expressionCache.put(expression, node);
    }
    return node;
  }

已经很明显了:mybatis通过调用ognl的类库实现mapper文件的if语法判断。具体ognl里边的源码就不往下看了,到这已经达到我的研究目的了。

最后附上一个main方法,便于读者学习测试,将下方main方法添加到org.apache.ibatis.scripting.xmltags.OgnlCache.java中即可

public static void main(String[] args)
  {
    String expression = null;
    try {
      HashMap<String, String> hashMap = new HashMap<>();
      hashMap.put("user", "xuliang");
      hashMap.put("pwd", "7788");
      expression = "(user != null and pwd == '2345') or pwd=='7788'";
      Map context = Ognl.createDefaultContext(hashMap, MEMBER_ACCESS, CLASS_RESOLVER, null);
      System.out.println(Ognl.getValue(parseExpression(expression), context, hashMap));
    } catch (OgnlException e) {
      throw new BuilderException("Error evaluating expression '" + expression + "'. Cause: " + e, e);
    }
  }

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值