Mybatis系列(二)配置文件源码解析


上篇文章 Mybatis系列(一)环境搭建,写了一个demo,大致了解了整个项目的流程。本节我们就来看看Mybatis的这么配置文件是如何实现的。

一、Mybatis入口

看一下上节的Test类

public static SqlSessionFactory getSessionFactory(){
    SqlSessionFactory sqlSessionFactory = null;
    String resource = "mybatis-config.xml";
    try {
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader(resource));
    } catch (IOException e) {
        e.printStackTrace();
    }
    return sqlSessionFactory;
}

Test类是通过SqlSessionFactoryBuilder去创建的SqlSessionFactory,然后又通过SqlSessionFactory创建SqlSession,可见SqlSessionFactoryBuilder是Mybatis代码的入口,我们就先从它入手。

二、SqlSessionFactoryBuilder源码

public class SqlSessionFactoryBuilder {
    public SqlSessionFactoryBuilder() {
    }
	
	//Reader读取mybatis配置文件,传入构造方法
	//除了Reader外,mybatis也提供了inputStream作为参数的构造方法
    public SqlSessionFactory build(Reader reader) {
        return this.build((Reader)reader, (String)null, (Properties)null);
    }

	//mybatis配置文件 + environment
    public SqlSessionFactory build(Reader reader, String environment) {
        return this.build((Reader)reader, environment, (Properties)null);
    }

	//mybatis配置文件 + properties
    public SqlSessionFactory build(Reader reader, Properties properties) {
        return this.build((Reader)reader, (String)null, properties);
    }

	//mybatis配置文件 + environment + properties,其实不管传入多少个参数,最终都是通过build方法创建SqlSessionFactory
    public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
        SqlSessionFactory var5;
        try {
            XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
            var5 = this.build(parser.parse());
        } catch (Exception var14) {
            throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
        } finally {
            ErrorContext.instance().reset();

            try {
                reader.close();
            } catch (IOException var13) {
            }

        }

        return var5;
    }

    public SqlSessionFactory build(InputStream inputStream) {
        return this.build((InputStream)inputStream, (String)null, (Properties)null);
    }

    public SqlSessionFactory build(InputStream inputStream, String environment) {
        return this.build((InputStream)inputStream, environment, (Properties)null);
    }

    public SqlSessionFactory build(InputStream inputStream, Properties properties) {
        return this.build((InputStream)inputStream, (String)null, properties);
    }

    public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
        SqlSessionFactory var5;
        try {
            XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
            var5 = this.build(parser.parse());
        } catch (Exception var14) {
            throw ExceptionFactory.wrapException("Error building SqlSession.", var14);
        } finally {
            ErrorContext.instance().reset();

            try {
                inputStream.close();
            } catch (IOException var13) {
            }

        }

        return var5;
    }

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

由上可以看出:

  1. Mybatis通过I/O流获取XML文件,字节流Reader和字符流InputStream两种方式均可。
  2. 每种读取方法都有多个重载方法,用来支持多种参数组合
  3. 但是最终都调用build(Configuration config)方法,返回DefaultSqlSessionFactory对象

通过源码,我们可以看到SqlSessionFactoryBuilder通过XMLConfigBuilder去解析我们传入mybatis的配置文件

三、XMLConfigBuilder源码

	//mybatis配置文件解析
    public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {
        this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);
    }
	private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
        super(new Configuration());
        ErrorContext.instance().resource("SQL Mapper Configuration");
        this.configuration.setVariables(props);
        this.parsed = false;
        this.environment = environment;
        this.parser = parser;
    }

	//外部调用此方法对mybatis配置文件解析
    public Configuration parse() {
        if (this.parsed) {
            throw new BuilderException("Each XMLConfigBuilder can only be used once.");
        } else {
            this.parsed = true;
            //根节点configuration
            
            this.parseConfiguration(this.parser.evalNode("/configuration"));
            return this.configuration;
        }
    }

	//此方法就是解析configuration节点下的子节点
	//由此也可看出,我们在configuration下面能配置的节点为以下10个节点
    private void parseConfiguration(XNode root) {
        try {
            this.propertiesElement(root.evalNode("properties"));
            this.typeAliasesElement(root.evalNode("typeAliases"));
            this.pluginElement(root.evalNode("plugins"));
            this.objectFactoryElement(root.evalNode("objectFactory"));
            this.objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));
            this.settingsElement(root.evalNode("settings"));
            this.environmentsElement(root.evalNode("environments"));
            this.databaseIdProviderElement(root.evalNode("databaseIdProvider"));
            this.typeHandlerElement(root.evalNode("typeHandlers"));
            this.mapperElement(root.evalNode("mappers"));
        } catch (Exception var3) {
            throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + var3, var3);
        }
    }

通过以上源码可以看到,mybatis配置文件中:

  1. 对Mybatis配置文件XML解析需要new一个XMLConfigBuilder对象。

  2. 调用解析器的parse()方法,解析XML文件信息,并返回一个Configuration对象,Configuration对象包含XML对应的子节点

  3. configuration为根节点,在configuration节点下,有10个子节点,分别是:properties、typeAliases、plugins、objectFactory、objectWrapperFactory、settings、environments、databaseIdProvider、typeHandlers、mappers。

  4. SqlSessionFactoryBuilder最终返回的是一个 DefaultSqlSessionFactory对象。

四、mybatis核心组件

这节我们主要介绍了mybatis核心组件之一的SqlSessionFactoryBuilder组件,它时如何解析mybatis的xml配置文件。mybatis核心组件主要包含:

  • SqlSessionFactoryBuilder(构造器):他会根据配置或者代码生成SqlSessionFactory,采用的是分步构建的Builder模式。
  • SqlSessionFactory(工厂接口):依靠它来生成SqlSession,使用的是工厂模式。
  • SqlSession(会话):一个既可以发送SQL执行返回结果,也可以获取Mapper的接口,在现有的技术中,一般我们会让其在业务逻辑代码中“消失”,而使用的是Mybatis提供的SQL
    Mapper接口编程技术,它能提高代码的可读性和可维护性。
  • SQL
    Mapper(映射器):Mybatis新设计存在的组件,它由一个java接口和XML文件(或注解)构成,需要给出对应的SQL和映射规则。它负责发送SQL去执行,并返回结果。

以及刚刚提到的configuration下的子节点,我们下节再深入介绍。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mybatis是一个轻量级的Java持久层开源框架,它封装了JDBC操作数据库的底层细节,提供了一个简单易用的数据库访问方式。 Mybatis源码分为核心模块和附加模块两部分,核心模块主要包括配置解析、SQL解析、SQL执行等功能,附加模块包括连接池、缓存、事务管理等功能。 在Mybatis源码中,配置解析是其中的关键部分。通过解析mybatis-config.xml配置文件,可以获取到数据库连接信息、映射器配置、插件配置等。在配置解析过程中,Mybatis会对配置文件进行校验,确保配置的正确性。 SQL解析Mybatis的另一个重要功能。Mybatis通过解析Mapper接口中的注解或XML配置文件中的SQL语句,将SQL语句解析为ParameterMapping、BoundSql等对象,并将其封装成一个MappedStatement对象,供后续的SQL执行使用。 SQL执行是Mybatis的核心功能之一。在SQL执行阶段,Mybatis会根据MappedStatement中的信息,获取数据库连接,并执行对应的SQL语句。在执行过程中,Mybatis会通过TypeHandler对参数进行类型转换,并使用ResultSetHandler将查询结果封装成Java对象。 除了核心模块,Mybatis源码还包括了连接池、缓存、事务管理等附加模块的实现。连接池模块负责管理数据库连接的获取和释放,缓存模块负责缓存查询结果以提高性能,而事务管理模块则负责管理数据库的事务处理。 总之,Mybatis源码解析涉及多个关键模块的实现,包括配置解析、SQL解析、SQL执行、连接池、缓存、事务管理等。通过了解这些模块的实现原理,我们可以更好地理解和使用Mybatis框架。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值