Mybatis源码分析(02)-配置文件解析概述

文章目录

      • 使用Mybatis操作数据库
      • SqlSessionFactoryBuilder
      • BaseBuilder
      • XMLConfigBuilder

使用Mybatis操作数据库

使用Mybatis操作数据库的基本写法如下:


	@Test
    public void testMybatis(){
        //1.加载配置文件
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        //建造者设计模式
        //2.解析配置文件,封装成Configuration 创建DefaultSqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        //3.生产了DefaultSqlsession实例对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        
        //传统方式,根statementid从map中获取MappedStatement对象
        //List list = sqlSession.selectList("com.mybaits.test.AccountDao.findAll");
        //4.代理方式,得到代理类对象
        AccountDao accountDao = sqlSession.getMapper(AccountDao.class);  
        //5.完成crud
        List<Account>list = accountDao.findAll();
        ...
    }
}

SqlSession是应用程序和mybatis交互的核心接口,而创建SqlSession对象之前还有一系列的前序操作,包括:

  1. 加载配置文件,由Resources.getResourceAsStream()完成。应用程序需要提供给Mybatis的配置文件有核心配置文件(上面程序中的sqlMapConfig.xml,实际使用不一定是这个名称),以及映射配置文件(一般会命名为xxxMapper.xml),映射配置文件的路径会配置在核心配置文件的标签下,所以外部加载的时候只加载核心配置文件就够了。在之后的解析过程中,核心配置文件大部分内容会被保存在全局唯一的Configuration对象中

  2. 创建SqlSessionFactoryBuilder对象,从应用程序的角度看,该对象完成了两个任务:

    • 将配置文件解析为Configuration对象

    • 创建SqlSessionFactory对象,将Configuration对象传递给SqlSessionFactory对象,并返回SqlSessionFactory对象

  3. SqlSessionFactory对象主要用于生产SqlSession

SqlSessionFactoryBuilder

使用SqlSessionFactoryBuilder的入口是SqlSessionFactoryBuilder.build()方法

具体实现如下:

public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
  try {
    //创建XMLConfigBuilder,用于解析mybatis配置文件
    XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
    //解析配置文件得到Configuration对象,创建DefaultSqlSessionFactory对象
    return build(parser.parse());
  } catch (Exception e) {
    throw ExceptionFactory.wrapException("Error building SqlSession.", e);
  } finally {
    ErrorContext.instance().reset();
    try {
      inputStream.close();
    } catch (IOException e) {
      // Intentionally ignore. Prefer previous error.
    }
  }
}

而这个方法在返回时调用的build()方法实现如下:

public SqlSessionFactory build(Configuration config) {
  return new DefaultSqlSessionFactory(config);  
}

BaseBuilder

显然,SqlSessionFactoryBuilder中的重点在配置文件解析上,回到最初的build()方法,里面创建了一个XMLConfigBuilder对象,而XMLConfigBuilder对象继承自BaseBuilder,事实上,在上一章提到的Mybatis整体架构中,核心处理层的配置解析,主要就是由BaseBuilder及其子类完成的。

查看BaseBuilder的继承与依赖关系,如下图所示:
Mybatis源码分析(02)-配置文件解析概述_第1张图片

BaseBuilder中定义了以下三个属性:

public abstract class BaseBuilder {
  //configuration保存Mybatis中几乎全部的配置信息,
  protected final Configuration configuration;
  //核心配置文件可以使用标签定义别名,别名会记录在typeAliasRegistry对象中
  protected final TypeAliasRegistry typeAliasRegistry;
  //核心配置文件可以使用标签添加自定义TypeHandler器,完成指定数据库类型与Java类型的转换
  //这些TypeHandler会记录在typeHandlerRegistry中
  protected final TypeHandlerRegistry typeHandlerRegistry;
  ...

另外BaseBuilder中的parseExpression用于解析配置文件中的正则表达式,booleanValueOf,integerValueOf,stringSetValueOf方法,从定义上看,应该是用于转换配置文件中的属性值字符串的类型,并且在没有配置属性的时候就使用默认值。

protected Pattern parseExpression(String regex, String defaultValue) {
  return Pattern.compile(regex == null ? defaultValue : regex);
}

protected Boolean booleanValueOf(String value, Boolean defaultValue) {
  return value == null ? defaultValue : Boolean.valueOf(value);
}

protected Integer integerValueOf(String value, Integer defaultValue) {
  return value == null ? defaultValue : Integer.valueOf(value);
}

protected Set<String> stringSetValueOf(String value, String defaultValue) {
  value = value == null ? defaultValue : value;
  return new HashSet<>(Arrays.asList(value.split(",")));
}

此外,resolveAlias()方法用于解析别名,resolveTypeHandler()方法查找指定的TypeHandler对象。

resolveJdbcType(),resolveResultSetType(),resolveParameterMode()这几个方法会将String转换为对应的JdbcType枚举类型、ResultSetType枚举类和ParameterMode枚举类,此处不做赘述,之后还会提到。

XMLConfigBuilder

XMLConfigBuilder完成了解析核心配置文件的任务。在Mybatis的核心配置文件中,主要有以下几种标签:

  • properties 属性

  • settings 设置

  • typeAliases 类型别名

  • typehandlers 类型处理器

  • objectFactory 对象工厂

  • plugins 插件

  • environments 环境

    • enviroment 环境变量
      • transactionManager 事务管理器
      • dataSource 数据源
  • databaseidProvider 数据库厂商标识

  • mappers 映射器

    XMLConfigBuilder也比较清晰地定义了每个标签的解析方法:
    Mybatis源码分析(02)-配置文件解析概述_第2张图片

进行解析的入口是XMLConfigBuilder.parse()方法,会调用XpathParser对象将根标签进行解析,传给XMLConfigBuilder.parseConfiguration()方法:

public Configuration parse() {
  //如果已解析,抛出BuilderException异常
  if (parsed) {
    throw new BuilderException("Each XMLConfigBuilder can only be used once.");
  }
  parsed = true;
  //parser是XpathParser解析器对象,读取节点内数据
  parseConfiguration(parser.evalNode("/configuration"));
  return configuration;
}

XMLConfigBuilder.parseConfiguration()逐个对每个子标签调用对应的解析方法,下一章中将重点关注XMLConfigBuilder.mapperElement()方法,该方法用于对mapper标签进行解析。

你可能感兴趣的:(#,java,Mybatis,数据库)