MyBatis-获取 SqlSession(源码)

Main 方法,mybatis 版本为 3.5.0

返回一个 DefaultSQlSession 对象,包含 Executor 和 Configuration

InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
session = sqlSessionFactory.openSession();

sqlSessionFactory.openSession()

org.apache.ibatis.session.defaults.DefaultSqlSessionFactory

private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    Transaction tx = null;
    try {
        final Environment environment = configuration.getEnvironment();
        final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
        // 通过事务工厂来产生一个事务
        tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
        // 生成一个执行器(事务包含在执行器里)
        final Executor executor = configuration.newExecutor(tx, execType);
        // 产生一个 DefaultSqlSession
        return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (Exception e) {
        // 如果打开事务出错,则关闭它
        closeTransaction(tx); // may have fetched a connection so lets call close()
        throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    } finally {
        // 清空错误上下文
        ErrorContext.instance().reset();
    }
}

configuration.newExecutor(tx, execType)

org.apache.ibatis.session.Configuration

// 产生执行器
    public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
        executorType = executorType == null ? defaultExecutorType : executorType;
        // 防止将 defaultExecutorType 设成 null ?
        executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
        Executor executor;
        // 简单的3个分支,产生 3 种执行器 BatchExecutor/ReuseExecutor/SimpleExecutor,用来执行 CURD 操作
        if (ExecutorType.BATCH == executorType) {
            executor = new BatchExecutor(this, transaction);
        } else if (ExecutorType.REUSE == executorType) {
            executor = new ReuseExecutor(this, transaction);
        } else {
            executor = new SimpleExecutor(this, transaction);
        }
        // 如果二级缓存,生成另一种 CachingExecutor(默认有一级缓存),装饰者模式,所以默认都是返回 CachingExecutor
        if (cacheEnabled) {
            executor = new CachingExecutor(executor);
        }
        // 此处调用插件,通过插件可以改变 Executor 行为
        executor = (Executor) interceptorChain.pluginAll(executor);
        return executor;
    }

new CachingExecutor(executor)

org.apache.ibatis.executor.CachingExecutor

/**
 * 二级缓存执行器
 */
public class CachingExecutor implements Executor {

    private final Executor delegate;
    private final TransactionalCacheManager tcm = new TransactionalCacheManager();

    public CachingExecutor(Executor delegate) {
        this.delegate = delegate;
        delegate.setExecutorWrapper(this);
    }

return new DefaultSqlSession(configuration, executor, autoCommit)

org.apache.ibatis.session.defaults.DefaultSqlSession

/**
 * 默认SqlSession实现
 */
public class DefaultSqlSession implements SqlSession {

    private final Configuration configuration;
    private final Executor executor;

    // 是否自动提交
    private final boolean autoCommit;
    private boolean dirty;
    private List<Cursor<?>> cursorList;

    public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
        this.configuration = configuration;
        this.executor = executor;
        this.dirty = false;
        this.autoCommit = autoCommit;
    }

时序图


https://github.com/tuguangquan/mybatis/tree/master/src/main/java/org/apache/ibatis

原文地址:https://www.cnblogs.com/jhxxb/p/10560551.html