?我們接著上一篇Mybatis(2)鄙煤,我們來(lái)看看上面獲取SqlSession:
我們從mybatis主要構(gòu)件的執(zhí)行流程:
我們先來(lái)SqlSessionFactory是什么獲取SqlSession的:SqlSessionFactory.openSession():
public SqlSession openSession() {
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
//從上下文中獲取當(dāng)前環(huán)境
final Environment environment = configuration.getEnvironment();
//從當(dāng)前環(huán)境中獲取事物工廠
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
//創(chuàng)建事物對(duì)象
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
//Executor 執(zhí)行器
final Executor executor = configuration.newExecutor(tx, execType);
//創(chuàng)建SqlSession
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();
}
}
這里我們關(guān)注下configuration.newExecutor(tx, execType):
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
//批量的
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);
}
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
以上代碼Executor的類(lèi)型:
ExecutorType.SIMPLE: 這個(gè)執(zhí)行器類(lèi)型不做特殊的事情。它為每個(gè)語(yǔ)句的執(zhí)行創(chuàng)建一個(gè)新的預(yù)處理語(yǔ)句断楷。
ExecutorType.REUSE: 這個(gè)執(zhí)行器類(lèi)型會(huì)復(fù)用預(yù)處理語(yǔ)句。
ExecutorType.BATCH: 這個(gè)執(zhí)行器會(huì)批量執(zhí)行所有更新語(yǔ)句奶赠。
接著我們關(guān)注下:
executor = (Executor) interceptorChain.pluginAll(executor) :
public class InterceptorChain {
private final List<Interceptor> interceptors = new ArrayList<Interceptor>();
public Object pluginAll(Object target) {
for (Interceptor interceptor : interceptors) {
target = interceptor.plugin(target);
}
return target;
}
public void addInterceptor(Interceptor interceptor) {
interceptors.add(interceptor);
}
public List<Interceptor> getInterceptors() {
return Collections.unmodifiableList(interceptors);
}
}
以上的代碼其實(shí)調(diào)用plugs鏈對(duì)目標(biāo)類(lèi)(Executor)繼續(xù)進(jìn)一步的處理近刘。這里plugs我們后續(xù)專(zhuān)門(mén)類(lèi)了解,這里只需要知道下在獲取SqlSession是初時(shí)候Execute執(zhí)行器橘沥,通過(guò)plugs可以對(duì)Execute進(jìn)行處理窗轩。
這邊順便提下SqlSession的四大對(duì)象:
1、Executor 執(zhí)行器:來(lái)調(diào)度StatementHandler座咆、ParameterHandler痢艺、ResultHandler等來(lái)執(zhí)行對(duì)應(yīng)的sql。
2介陶、StatementHandler:數(shù)據(jù)會(huì)話(huà)器使用數(shù)據(jù)庫(kù)的Statement(PreparedStatement)執(zhí)行操作堤舒,它是四大對(duì)象的核心,起到承上啟下的作用哺呜。
3舌缤、ParameterHandler:用于Sql對(duì)參數(shù)的處理
4、ResultHandler:進(jìn)行最后的數(shù)據(jù)集(ResultSet)的封裝返回處理的。