MyBatis运行流程

Main函数

首先来看看sqlSessionFactory对象的创建过程

sqlSessionFactory的创建需要有Builder来build(),所以我们先看看build方法:

    public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
        SqlSessionFactory var5;
        try {
            //创建一个xml解析器
            XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
            //通过xml构建SqlSessionFactory 
            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;
    }

可以看到,build方法中,首先是创建一个xml解析器,解析器的种类有很多,但是都有一个基类 BaseBuilder

这个基类有三个属性,根据名字便可以知道是配置对象,别名注册对象,类型拦截器

解析完后调parser.parse()返回一个Configuration对象:

我们来看看parseConfiguration方法:

解析配置文件种的各个节点,我们来看下解析mappers节点的过程:

拿到接口注册:

Configuration对象就是一个封装了配置文件中<configuration>标签里的配置信息的对象:

并将配置信息放入SqlSessionFactory中,接下来就是通过SqlSessionFactory拿到SqlSession对象.

    private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
        Transaction tx = null;

        DefaultSqlSession var8;
        try {
            Environment environment = this.configuration.getEnvironment();
//获取事务管理器
            TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);
            tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
            //获取sql的执行对象
            Executor executor = this.configuration.newExecutor(tx, execType);
            //获取sqlSession对象
            var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);
        } catch (Exception var12) {
            this.closeTransaction(tx);
            throw ExceptionFactory.wrapException("Error opening session.  Cause: " + var12, var12);
        } finally {
            ErrorContext.instance().reset();
        }

        return var8;
    }

Mybatis中所有的Mapper语句的执行都是通过Executor进行的,Executor是Mybatis的一个核心接口,其定义如下。从其定义的接口方法我们可以看出,对应的增删改语句是通过Executor接口的update方法进行的,查询是通过query方法进行的。虽然Executor接口的实现类有BaseExecutor和CachingExecutor,而BaseExecutor的子类又有SimpleExecutor、ReuseExecutor和BatchExecutor,但BaseExecutor是一个抽象类,其只实现了一些公共的封装,而把真正的核心实现都通过方法抽象出来给子类实现,如doUpdate()、doQuery();CachingExecutor只是在Executor的基础上加入了缓存的功能,底层还是通过Executor调用的,所以真正有作用的Executor只有SimpleExecutor、ReuseExecutor和BatchExecutor。

接下来我们主要来看看 var8 = new DefaultSqlSession(this.configuration, executor, autoCommit);

拿到sqlSession后就可以通过getMapper来获取了,我们来看看这个方法:

可以看到,它是从原来的knownMappers中获取,并通过反射创建代理对象

猜你喜欢

转载自blog.csdn.net/qq_41750725/article/details/87950915