聊聊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()办法剖析了它的一级缓存的实现