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