mybatis的执行器(Executor)创建过程
Executor是mybatis里面的核心对象之一,他提供了crud功能,可以认为这是一个门面。Executor有很多实现类。但是默认情况下,在你不配置Executor的类型的时候,会创建一个SimpleExecutor。
下面看一下他的类结构
那我们就来看看这个执行器是怎么创建的。
核心的地方就是在我们获取SqlSession对象的时候,创建了执行器。
DefaultSqlSessionFactory:
@Override
public SqlSession openSession() {
/**
* 设置了一个默认的Executor 默认为simple
* configuration.getDefaultExecutorType() 执行器的类型,默认为simple
* 并且设置为手动提交事务
*/
return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
这个configuration对象,就是解析我们mybatis的配置文件生成的对象。其实我们可以在mybatis的配置文件设置执行器的类型。这里暂时忽略吧。今天只讲simple这个执行器的生成。
继续看下面这个方法
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);
//获取执行器的时候,进行了mybatis插件的添加
final Executor executor = configuration.newExecutor(tx, execType);
/**
* 创建了一个默认的DefaultSqlSession
* 并且DefaultSqlSession持有Configuration对象 还有执行器(cache) 设置了自动提交
* 这个executor有可能是代理对象 executor中包含事务对象
* 所以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();
}
}
先看这行代码
final Executor executor = configuration.newExecutor(tx, execType);
这行代码就是配置文件解析生成的对象来创建一个执行器,参数就是mybatis生成的事务管理器和执行器类型(simple)。
进去这个方法看看
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
//这两行就是继续判断执行器类型,默认是simple
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 {
//如果是simple,走这里
executor = new SimpleExecutor(this, transaction);
}
//默认为true,这个参数也可以在mybatis的配置文件中进行配置
if (cacheEnabled) {
//又套娃了,装饰器模式
executor = new CachingExecutor(executor);
}
//调用插件,如果有配置的插件,那么返回代理对象,层层代理。套千层饼
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
这段代码难度不是很大,我们看这一行
if (cacheEnabled) {
//又套娃了,装饰器模式
executor = new CachingExecutor(executor);
}
这里又进行了一次包装,这个CachingExecutor也是一个执行器,跟simple是兄弟关系。那么为什么要套一层呢?主要还是跟mybatis的缓存有关系。这里使用了装饰器模式。目的就是对功能的增强。
那这个又在干什么呢?
executor = (Executor) interceptorChain.pluginAll(executor);
这个是mybatis的插件机制。稍微复杂。其实PageHelper这个分页对象,就是利用了mybatis的插件机制。如果你配置了插件,那么有可能,你的执行器会是一个代理对象。只是有可能,不一定。这个要看你的插件代码怎么写。
这里不废话了。有机会给大家介绍mybatis插件。
好,关于执行器的创建就粗略分享这么多。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?