上篇文章介紹了mybatis中的關(guān)鍵對(duì)象SqlSessionFactory的創(chuàng)建過程,本篇文章繼續(xù)介紹下執(zhí)行器executor。每個(gè)SqlSession都會(huì)擁有一個(gè)Executor對(duì)象,這個(gè)對(duì)象負(fù)責(zé)增刪改查操作,我們可以簡(jiǎn)單的將它理解為JDBC中Statement的封裝版
executor繼承結(jié)構(gòu)

- Executor接口:有兩個(gè)實(shí)現(xiàn)類BaseExecutor、CachingExecutor
- BaseExecutor:是一個(gè)抽象類,抽象類實(shí)現(xiàn)接口是”適配器模式“的體現(xiàn),為了方便下一級(jí)實(shí)現(xiàn)類對(duì)接口中方法的實(shí)現(xiàn);BaseExecutor有三個(gè)子類分別是simpleExecutor、ResuseExecutor、BatchExecutor
- SimpleExecutor:是MyBatis中默認(rèn)使用的執(zhí)行器. 每執(zhí)行一次update或select,就開啟一個(gè)Statement對(duì)象,用完立刻關(guān)閉Statement對(duì)象。(可以是Statement或PrepareStatement對(duì)象)
- ReuseExecutor:可重用執(zhí)行器,這里的重用指的是重復(fù)使用Statement. 它會(huì)在內(nèi)部利用一個(gè)Map把創(chuàng)建的Statement都緩存起來,每次在執(zhí)行一條SQL語句時(shí),它都會(huì)去判斷之前是否存在基于該SQL緩存的Statement對(duì)象,存在而且之前緩存的Statement對(duì)象對(duì)應(yīng)的Connection還沒有關(guān)閉的時(shí)候就繼續(xù)用之前的Statement對(duì)象,否則將創(chuàng)建一個(gè)新的Statement對(duì)象,并將其緩存起來。因?yàn)槊恳粋€(gè)新的SqlSession都有一個(gè)新的Executor對(duì)象,所以我們緩存在ReuseExecutor上的Statement的作用域是同一個(gè)SqlSession
- BatchExecutor:批處理執(zhí)行器,.用于將多個(gè)sql語句一次性輸送到數(shù)據(jù)庫執(zhí)行.
- CachingExecutor:緩存執(zhí)行器, 先從緩存中獲取查詢結(jié)果,存在就返回,不存在,再委托給Executor delegate去數(shù)據(jù)庫取,delegate可以是上面任一的SimpleExecutor、ReuseExecutor、BatchExecutor
Executor的創(chuàng)建
在SqlSessionFactory創(chuàng)建完成后,調(diào)用openSession方法:
public SqlSession openSession() {
return this.openSessionFromDataSource(this.configuration.getDefaultExecutorType(), (TransactionIsolationLevel)null, false);
}
在SqlSessionFactory的默認(rèn)實(shí)現(xiàn)類DefaultSqlSessionFactory可以看到openSession中調(diào)用了openSessionFromDataSource,在這個(gè)方法中會(huì)創(chuàng)建一個(gè)執(zhí)行器,代碼如下
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;
}
執(zhí)行器對(duì)象是由Coniguration對(duì)象負(fù)責(zé)創(chuàng)建的.Configuration對(duì)象會(huì)根據(jù)得到ExecutorType創(chuàng)建對(duì)應(yīng)的Excecutor對(duì)象,并把這個(gè)Excecutor對(duì)象傳給SqlSession對(duì)象
ExcecutorType的選擇
ExecutorType來決定Configuration對(duì)象創(chuàng)建何種類型的執(zhí)行器.它的賦值可以通過兩個(gè)地方進(jìn)行賦值.
首先.可以通過<settings>標(biāo)簽來設(shè)置當(dāng)前工程中所有SqlSession對(duì)象使用的默認(rèn)Executour

也可以通過SqlSessoinFactory中openSession方法來指定具體的SqlSession使用的執(zhí)行器

原文地址