美文网首页
Mybatis运行原理02-构建sqlSession

Mybatis运行原理02-构建sqlSession

作者: 布拉德老瓜 | 来源:发表于2021-03-07 00:29 被阅读0次

在上一篇文章中,解析了SqlSessionFactory的创建过程:读取配置文件-->解析配置-->创建Configuration对象-->将mybatis配置属性、mapper等信息封装到Configuration对象内-->以configuration作为参数创建sqlSessionFactory。

在本文中,将讲述SqlSession的结构、作用以及创建过程。在 MyBatis 中,SqlSession 是一个重要接口,它相当于一个门面,起着连接应用与底层执行器executor的作用。通过它,用户可以来实现对数据的操作、事务的控制和mapper代理对象的获取。在 MyBatis 中有两个SqlSession实现类,DefaultSqlSession 和 SqlSessionManager。本文重点讲DefaultSqlSession,并将捎带一点SqlSessionManager。

1.SqlSession的创建过程

    public SqlSession openSession() {
        return this.openSessionFromDataSource(this.configuration.getDefaultExecutorType(), (TransactionIsolationLevel)null, false);
    }
/**
*      参数:execType:"SIMPLE", level: null, autoCommit: false
*/
    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);
            Executor executor = this.configuration.newExecutor(tx, execType);
            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;
    }

openSessionFromDataSource在创建SqlSession过程中做了3件事情:创建事务, 创建执行器, 创建sqlSession。每一步的结果都作为下一步的参数,最终构建出一个可用来表示会话的sqlSession。事实上,sqlSession对象既不直接管理数据库的连接,也不直接操作数据,而是将功能交给了执行器--执行器负责doQuery,同时通过内部封装的tx对象来管理数据库连接和事务的提交/回滚。

  1. 创建事务工厂,用于创建事务,进行事务控制。做法很简单,若在配置文件中对environment配置了事务工厂,那么就从configuration的environment属性中获取transactionFactory,没有则新建一个ManagedTransactionFactory对象。然后由该工厂对象创建事务。
  TransactionFactory transactionFactory = this.getTransactionFactoryFromEnvironment(environment);          
  tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);

在mybatis中,事务的作用:获取连接、提交、回滚、关闭连接。

public interface Transaction {
    Connection getConnection() throws SQLException;

    void commit() throws SQLException;

    void rollback() throws SQLException;

    void close() throws SQLException;

    Integer getTimeout() throws SQLException;
}
  1. 创建执行器Executor


    Executor创建过程

    Executor有3种类型: Simple, Reuse, Batch.
    //todo:区别与共性

2.1 SimpleExecutor的创建
直接调用了父类BaseExecutor的构造方法。


SimpleExecutor的创建

2.2 创建成功之后,若启用了缓存,那么创建一个CachingExecutor并用其包装SimpleExecutor对象。
2.3 拦截器链为executor植入插件,使用插件完成对executor的代理。简单来说就是采用责任链模式,一层层的创建代理对象,最后返回终极版的executor代理对象。

    public Object pluginAll(Object target) {
        Interceptor interceptor;
        for(Iterator var2 = this.interceptors.iterator(); var2.hasNext(); target = interceptor.plugin(target)) {
            interceptor = (Interceptor)var2.next();
        }

        return target;
    }
    default Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }
    public static Object wrap(Object target, Interceptor interceptor) {
        //获取方法签名
        Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);
        Class<?> type = target.getClass();
        Class<?>[] interfaces = getAllInterfaces(type, signatureMap);        
        //创建代理对象
        return interfaces.length > 0 ? Proxy.newProxyInstance(type.getClassLoader(), interfaces, new Plugin(target, interceptor, signatureMap)) : target;
    }
  1. 创建SqlSession
    public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
        this.configuration = configuration;
        this.executor = executor;
        this.dirty = false;
        this.autoCommit = autoCommit;
    }

还是属性封装,将SqlSessionFactory对象的Configuration、刚创建的executor、autoCommit三个属性封装到sqlSession对象中。

到这里,sqlSession对象就创建并初始化了。它内部的核心组件就是负责完成与数据库交互的executor和封装配置属性的Configuration。它的作用主要有:通过configuration获取到mapper、通过executor完成crud、事务管理和连接管理。

相关文章

网友评论

      本文标题:Mybatis运行原理02-构建sqlSession

      本文链接:https://www.haomeiwen.com/subject/zrzsqltx.html