聊聊 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 默认开启一级缓存,是 SqlSession 级别的,即通过 SqlSession 建设会话,如果在这个会话中执行雷同的 sql,第一次执行的后果会进行缓存,再往后从缓存中查找
缓存数据
咱们从它的 query()办法来进行剖析:
@Override
public <E> List<E> 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<E>) 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()办法剖析了它的一级缓存的实现