聊聊Mybatis的Executor之模板方法模式
聊聊Mybatis的Executor之模板方法模式
模板方法模式通过模板方法来指定流程,具体的子类来实现具体的逻辑。
我们看一下Executor接口,它的实现类有BaseExecutor抽象类和CachingExecutor类
BaseExecutor
BaseExecutor抽象类作为模板方法的抽象模板类,它把缓存和事务进行实现,具体变化的对数据库操作的部分由子类去实现
提交事务方法
我们先说说事务管理的commit()方法的实现:
@Override
public void commit(boolean required) throws SQLException {
if (closed) {
throw new ExecutorException("Cannot commit, transaction is already closed");
}
clearLocalCache();
flushStatements();
if (required) {
transaction.commit();
}
}
清除一级缓存
调用flushStatements()方法,这个方法中调用doFlushStatements抽象方法,具体操作由子类来实现,主要功能就是清除Statement对象
最后提交事务
【聊聊Mybatis的Executor之模板方法模式】回滚事务的逻辑和这个提交逻辑基本一致,就不再分析了
Mybatis默认开启一级缓存,是SqlSession级别的,即通过SqlSession建立会话,如果在这个会话中执行相同的sql,第一次执行的结果会进行缓存,再往后从缓存中查找
缓存数据
我们从它的query()方法来进行分析:
@Override
public List query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
BoundSql boundSql = ms.getBoundSql(parameter);
聊聊Mybatis的Executor之模板方法模式
CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql);
return query(ms, parameter, rowBounds, resultHandler, key, boundSql);
}
list = resultHandler == null ? (List) localCache.getObject(key) : null;
deferredLoad.load();
我们可以知道,缓存是通过HashMap来存储的,而key是CacheKey对象,影响CacheKey对象的元素有哪些呢?
cacheKey.update(ms.getId());
cacheKey.update(rowBounds.getOffset());
cacheKey.update(rowBounds.getLimit());
cacheKey.update(boundSql.getSql());
我们通过createCacheKey()中就能看出决定CacheKey对象的因素有:MappedStatement(增删改查标签节点的封装)的id,RowBounds的offset属性和limit属性,还有对应的sql语句
总结
这篇文章主要讲了Mybatis的Executor接口和它的抽象实现类BaseExecutor,BaseExecutor是抽象类,它提供了事务管理和缓存的功能,我们从query()方法分析了它的一级缓存的实现
推荐阅读
- Linux操作系统负载的命令查看与详解
- 编程语言|想接私活时薪再翻一倍,建议根据这几个开源的SpringBoot项目(含小程序)改改~...
- 编程|想接私活时薪再翻一倍,建议根据这几个开源的SpringBoot项目(含小程序)改改~
- MyBatis-Plus的saveBatch批量插入为何效率很低,耗时很长,怎么解决()
- 中间件|比 Spring Boot 快 10 倍的 Bootique 框架
- 每日一思(18.5.8)【幸福的方法1】
- 读艾德勒《如何阅读一本书》【9】第九章判断作者的主旨
- PerfView专题|PerfView专题 (第九篇)(洞察 C# 中的 LOH 内存碎片化)
- 【井底望天】房子和芯片(时代价值观的变迁)
- The|The Void 将为《捉鬼敢死队》影迷带来一场基于 VR 的视觉体验