mybatis 源码分析之 解析mapper.xml文件

本文探讨了Mybatis如何解析mapper.xml文件,从mapperLocations开始,逐层剖析XMLMapperBuilder的parse方法。解析后的结果存储于Configuration对象中,包括ParameterMap、ResultMap和XNode等。通过源码分析,可以理解Mybatis的设计思想,如短key管理、建造者模式和模板方法模式的应用。
摘要由CSDN通过智能技术生成
  • mybatis 是如何解析我们定义的mapper.xml文件?解析后如何存储?存在哪里?
  • 想要解析必然先找到mapper.xml文件,mapperLocations  就是通过读取我们的配置获取到的xml Resource数组。
  private Resource[] mapperLocations;

mybatis.mapper-locations=classpath:/mapper/*.xml
  • 循环读取mapper文件,进行解析。
  • 接下来我们看下解析是如何进行的?
  • 首先构建了一个xmlMapperBuilder  对象,该对象包含了mapper.xml文件流,全路径文件名,Configuration 对象,以及当前对象的sqlFragments .即 sql 片段。
  • 接下来调用XMLMapperBuilder的parse方法进行具体的解析工作。具体方法如下。
      public void parse() {
    
        //这里首先判断该资源是否已经加载过,已加载则不处理。
        if (!configuration.isResourceLoaded(resource)) {
    
          configurationElement(parser.evalNode("/mapper"));
          configuration.addLoadedResource(resource);
          bindMapperForNamespace();
        }
    
        parsePendingResultMaps();
        parsePendingCacheRefs();
        parsePendingStatements();
      }
    
     // XPathParser 类 parser.evalNode("/mapper")  构造一个XNode 节点对象。
    public XNode evalNode(String expression) {
        return evalNode(document, expression);
      }
    
      public XNode evalNode(Object root, String expression) {
        Node node = (Node) evaluate(expression, root, XPathConstants.NODE);
        if (node == null) {
          return null;
        }
        return new XNode(this, node, variables);
      }
    
    // configurationElement  方法
      private void configurationElement(XNode context) {
        try {
           //  获取命名空间,可见mapper文件的命名空间不可为空也不能是空字符串  
          String namespace = context.getStringAttribute("namespace");
          if (namespace == null || namespace.equals("")) {
            throw new BuilderException("Mapper's namespace cannot be empty");
          }
           // 设置当前命名空间
          builderAssistant.setCurrentNamespace(namespace);
            // 解析cache-ref 相关配置
          cacheRefElement(context.evalNode("cache-ref"));
            // 解析cache配置
          cacheElement(context.evalNode("cache"));
            //  解析mapper 标签下parameterMap 配置 参数配置 
          parameterMapElement(context.evalNodes("/mapper/parameterMap"));
            // 解析 mapper/resultMap 标签,放入到configuration  的属性resultMaps  。key 是由我们当前mapper文件的命名空间和标签定义里的id 拼接而来的。这样不同的命名空间就可以只用相同的id定义,由此命名空间起到了隔离的作用。
    //  protected final Map<String, ResultMap> resultMaps = new StrictMap<>("Result Maps collection");
          resultMapElements(context.evalNodes("/mapper/resultMap"));
        // 解析sql标签 放入到  configuration   的属性sqlFragments 参数里,sql片段信息
    //   protected final Map<String, XNode> sqlFragments = new StrictMap<&g
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值