Mybatis源码阅读系列(二)

12 篇文章 0 订阅
9 篇文章 0 订阅

今天来看下Configuration这个类,顾名思义,它就是配置的意思,所有mybatis配置相关的信息都在里面能找到,是一个很重要的类,到底有多重要呢?你可以看到mybatis里面sqlsession和sqlsessionFactory这两个重要的接口里面都有getConfiguration的方法定义,我粗略看了下,感觉整个mybatis框架流转都会经过它(没经过验证,不一定对)。它里面持有了很多重要的属性,比如我们常用的typeAliasRegistry,mappedStatements,interceptorChain,mapperRegistry等都在里面。

我们知道,mybatis是通过加载配置完成整个sqlsessionFactory的创建,最后得到sqlsession的。所以mybatis的所有数据初始化都是根据Configuration来的,所以弄明白Configuration的工作原理对理解整个框架实现很有帮助,我们先从构造函数入手。

构造函数

可以看到构造函数有两种,无参的传入enviroment的。无参构造就是一些类型别名初始化。

在这里插入图片描述

TypeAliasRegistry

这里简单说下TypeAliasRegistry这个类,它的作用其实很简单,就是进行类型别名替换,我们在mybatis的xml文件配置的时候,都需要为其指定一个具体类型,类型必须是全路径,这样写起来很麻烦,如果多处使用那就要写好多次,这个类的作用就是解决这个问题,你只需要自己设置一个别名,然后直接使用别名就可以。

它里面持有一个typeAliases的Map,用来存储类型映射。可以看到它的构造函数其实一开始初始化了很多类型,这些你都直接可以在xml的type里面直接输入,可以看到都是一些基本类型和基本类型数组,还有date这些常用类型。

在这里插入图片描述

当然它在读取mybatis-config.xml的时候会将里面定义的type都注册进去。对应的是typeAliases这个标签。入口是在XMLConfigBuilder.typeAliasesElement方法,有兴趣可以自己去看下。

为了支持注解,它在实际注册类的时候会先拿到注解Alias里的值,然后再进行赋值。

  public void registerAlias(Class<?> type) {
    String alias = type.getSimpleName();
    Alias aliasAnnotation = type.getAnnotation(Alias.class);
    if (aliasAnnotation != null) {
      alias = aliasAnnotation.value();
    }
    registerAlias(alias, type);
  }

底层逻辑是如果有设置别名,就直接用别名赋值,没有使用,直接用类名小写赋值。

看源码的时候突然我想到一个问题,如果在xml和注解同时设置了不同的别名,那最后是哪个生效呢

我特意去看了下源码,主要取决于你利用什么配置生成的sqlsessionFacoty,如果是用的myabtis-config.xml生成,且没有使用package标签,那么注解生效。如果没有使用package标签,那么xml里面配置的生效。

在具体解析别名的时候拿到key去拿到对应类型,如果没有key,直接根据路径解析,在没有就会抛出异常。

  public <T> Class<T> resolveAlias(String string) {
    try {
      if (string == null) {
        return null;
      }
      // issue #748
      String key = string.toLowerCase(Locale.ENGLISH);
      Class<T> value;
      if (typeAliases.containsKey(key)) {
        value = (Class<T>) typeAliases.get(key);
      } else {
        value = (Class<T>) Resources.classForName(string);
      }
      return value;
    } catch (ClassNotFoundException e) {
      throw new TypeException("Could not resolve type alias '" + string + "'.  Cause: " + e, e);
    }
  }
Environment

我们在使用Configuration时,如果不是读入的mybatis-config.xml时,很多时候是自己构造Configuration,这时候就需要传入Environment,那么这个类具体是干嘛的呢?

首先看看它的属性有哪些,看了下就下面三个属性:

  private final String id;
  private final TransactionFactory transactionFactory;
  private final DataSource dataSource;

那其实就很简单了,Environment就是环境抽象,比如我们的dev,test,prod这种,每个环境会对应一个数据源和事务信息。

所以我们构造一个Configuration的步骤是

总结

今天简单看了下Configuration的构造函数,介绍了下构造函数里用到的两个类TypeAliasRegistry和Environment的作用。

最后简单梳理下如果我们不读取配置文件的流,而是要自己全部用java代码构建一个Sqlsession需要哪些东西呢?

  1. 构造Environment:构造数据源,有事务要求的话构造事务,在设定环境标识(id)
  2. 构造Configuration:利用前面创建的Environment构造Configuration
  3. 构造SqlsessionFacoty:利用sqlsessionFactoryBuilder和前面创建的Configuration构建SqlsessionFactory
  4. 构造Sqlsession:利用SqlsessionFacoty的openSession拿到sqlsession

拿到sqlsession之后你就可以愉快的操作mapper进行CRUD了。

明天我们继续看Configuration,敬请期待。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值