mybatis源码分析-1

Mybatis3源码分析(代码分析git地址

1. 项目层级图

在这里插入图片描述

2.主要内容

2.1annotations(注解)

annotations部分主要定义的是mybatis使用的各种注解。如@select,@delete,@update,@insert等,所有如下图。

在这里插入图片描述
注解的源码里面也注释了,这些注解怎么使用具体如下图。
在这里插入图片描述
:@转义为@

2.1binding(sql绑定)

在这里插入图片描述

2.1.1Mapper注册类

在这里插入图片描述
其中主要的操作逻辑都是围绕着knownMappers展开的,knownMappers定义如下

 private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<>();

config其中config是mybatis的配置和一些资源的挂载类还要一些其他作用,这里展示先不展开讲述,由于篇幅限制。

  private final Configuration config;
2.1.1.1addMapper方法逻辑(代码分析git地址
 public <T> void addMapper(Class<T> type) {
    
    
    if (type.isInterface()) {
    
    //判断mapper是不是接口,因为底层使用的是JDK动态代理,JDK代理是基于接口的。
      if (hasMapper(type)) {
    
    //判断这个mapper是否已经注册
        //已经注册报错
        throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
      }
      //加载是否完成标识符
      boolean loadCompleted = false;
      try {
    
    
        //knownMappers存放一个以 type为k,new MapperProxyFactory<>(type)(将新生成的type类型的mapper代理工厂类)为V
        knownMappers.put(type, new MapperProxyFactory<>(type));
        // It's important that the type is added before the parser is run
        // otherwise the binding may automatically be attempted by the
        // mapper parser. If the type is already known, it won't try.

        //生成MapperAnnotationBuilder用于解析mapper相关的xml和注解
        MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
        parser.parse();
         //解析完成 加载完成标识符为true
        loadCompleted = true;
      } finally {
    
    
        if (!loadCompleted) {
    
    //判断加载是否完成 未完成移除本次添加

          knownMappers.remove(type);
        }
      }
    }
  }

MapperAnnotationBuilder 生成分析

MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);

其中config是mybatis的配置和一些资源的挂载类,type是该mapper的全限定名。
MapperAnnotationBuilder类字段
在这里插入图片描述
构造类主要初始化了configurationassistanttype

  public MapperAnnotationBuilder(Configuration configuration, Class<?> type) {
    
    
    //通过全限定名推出 该类的资源地址
    String resource = type.getName().replace('.', '/') + ".java (best guess)";
    //mapper建造助手类
    this.assistant = new MapperBuilderAssistant(configuration, resource);
    //配置类
    this.configuration = configuration;
    //类型
    this.type = type;
  }

statementAnnotationTypes是一个注解类型的静态常量set集合

  private static final Set<Class<? extends Annotation>> statementAnnotationTypes = Stream
      .of(Select.class, Update.class, Insert.class, Delete.class, SelectProvider.class, UpdateProvider.class,
          InsertProvider.class, DeleteProvider.class)
      .collect(Collectors.toSet());

MapperAnnotationBuilder 的parse()过程

      parser.parse();

点击查看

  public void parse() {
    
    
    String resource = type.toString();
    if (!configuration.isResourceLoaded(resource)) {
    
          //配置类中该资源未被加载进行加载
      //加载mapper相对于的xml 以及解析xml中mapper的内容
      loadXmlResource();
      //配置类 中添加resource的记录 便于判断是否改资源已经加载
      configuration.addLoadedResource(resource);
      //将类名作为命名空间
      assistant.setCurrentNamespace(type.getName());
      //解析是否要缓存命名空间 与类一对一
      parseCache();
      //解析是否要缓存命名空间引用 与类 一对多
      parseCacheRef();
      //代理mapper方法
      for (Method method : type.getMethods()) {
    
    
        if (!canHaveStatement(method)) {
    
    
          //是桥接或者default方法不进行代理
          continue;
        }
        //@Select和@SelectProvider的方法进行解析
        //并且改方法上不存在@ResultMap注解
        if (getAnnotationWrapper(method, false, Select.class, SelectProvider.class).isPresent()
          && method.getAnnotation(ResultMap.class) == null) {
    
    
          //缺失@ResultMap情况下的 解析
          parseResultMap(method);
        }
        try {
    
    
          //解析动态sql Statement JDBC的Statement,PreStatement都是Statement(此次不止解析Statement还解析了方法上的 @Options存储等系列方法上的注解)
          parseStatement(method);
        } catch (IncompleteElementException e) {
    
    
          //解析出行异常 下文parsePendingMethods()会对解析出行异常的再次解析
          configuration.addIncompleteMethod(new MethodResolver(this, method));
        }
      }
    }
    //解析失败的方法重新 解析
    parsePendingMethods();
  }

由于篇幅限制各个函数深入的分析可看一下我的git地址(代码分析git地址

猜你喜欢

转载自blog.csdn.net/qq_39165528/article/details/108986161