微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

聊聊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();
    }
  }
  1. 清除一级缓存
  2. 调用flushStatements()方法,这个方法调用doFlushStatements抽象方法,具体操作由子类来实现,主要功能就是清除Statement对象
  3. 最后提交事务

回滚事务的逻辑和这个提交逻辑基本一致,就不再分析了

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);
    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()方法分析了它的一级缓存的实现。

来源:https://blog.51cto.com/u_15460453/5611604

原文地址:https://www.jb51.cc/wenti/3285906.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐