小白之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地址

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值