• 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

  • 相关阅读:
    Spark技术栈
    Linux rm -rf删除文件不释放空间的解决办法
    MySQL 5.6.35 索引优化导致的死锁案例解析
    亲历者说 | 完整记录一年多考拉海购的云原生之路 转
    Spark实战(八)spark的几种启动方式
    Spark实战(七)spark streaming +kafka(Python版)
    stm32 IAP + APP ==>双剑合一
    Flask-APScheduler定时任务查询操作数据库(多文件/模块)
    flask框架开启定时任务简单案例flask_apscheduler
    Flask数据的增删改查(CRUD)
  • 原文地址:https://www.cnblogs.com/jhxxb/p/10560551.html
Copyright © 2020-2023  润新知