mybatis源码学习------执行器Executor(一)

本文深入探讨mybatis的核心接口Executor及其基本实现BaseExecutor,讲解Executor的职责,包括缓存、事务管理和数据库操作。BaseExecutor实现了大部分接口,提供一级缓存和事务处理,子类如BatchExecutor、ReuseExecutor、SimpleExecutor只需实现特定功能。同时,文章介绍了缓存key的生成、事务控制以及延迟加载等关键功能。
摘要由CSDN通过智能技术生成

Executor

该接口中定义了操作数据库的各种方法,是mybatis的核心接口之一,是SqlSession接口的基础,其定义如下:

public interface Executor {
   

  ResultHandler NO_RESULT_HANDLER = null;
  //执行增删改操作
  int update(MappedStatement ms, Object parameter) throws SQLException;
  //执行查询操作
  <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException;

  <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;

  <E> Cursor<E> queryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds) throws SQLException;
  //批量执行sql
  List<BatchResult> flushStatements() throws SQLException;
  //提交事务
  void commit(boolean required) throws SQLException;
  //回滚事务
  void rollback(boolean required) throws SQLException;
  //创建缓存的key
  CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql);
  //是否已缓存
  boolean isCached(MappedStatement ms, CacheKey key);
  //清空一级缓存
  void clearLocalCache();
  //延迟加载一级缓存中的数据
  void deferLoad(MappedStatement ms, MetaObject resultObject, String property, CacheKey key, Class<?> targetType);
  //获取事务对象
  Transaction getTransaction();
  //关闭执行器
  void close(boolean forceRollback);
  //是否关闭
  boolean isClosed();
  //设置委派的执行器对象
  void setExecutorWrapper(Executor executor);

}

类图

在这里插入图片描述

Executor接口及其实现使用了模板设计模式,抽象类BaseExecutor实现了Executor接口中的大部分方法,BatchExecutor、ReuseExecutor和SimpleExecutor只需要根据自身的需求实现少量的方法即可,利用面向对象多态的特性,提高了系统的灵活性和扩展性。

BaseExecutor

抽象类BaseExecutor是Executor接口的基本实现,他实现了大部分接口,提供了缓存和事务相关的实现,使得其子类只需要实现和数据库相关的功能即可。

属性

private static final Log log = LogFactory.getLog(BaseExecutor.class);
//事务对象
protected Transaction transaction;
//持有的执行器对象
protected Executor wrapper;
//延迟加载队列
protected ConcurrentLinkedQueue<DeferredLoad> deferredLoads;
//一级缓存
protected PerpetualCache localCache;
//保存输出参数的缓存
protected PerpetualCache localOutputParameterCache;
//全局配置对象
protected Configuration configuration;
//嵌套查询层数
protected int queryStack;
//Executor是否已经被关闭的标志位
private boolean closed;

构造函数

protected BaseExecutor(Configuration configuration, Transaction transaction) {
   
  this.transaction = transaction;
  this.deferredLoads = new ConcurrentLinkedQueue<>();
  this.localCache = new PerpetualCache("LocalCache");
  this.localOutputParameterCache = new PerpetualCache("LocalOutputParameterCache");
  this.closed = false;
  this.configuration = configuration;
  this.wrapper = this;
}

缓存相关

这里的缓存就是常说的一级缓存,缓存的优势不用多说,这里需要强调的是mybatis一级缓存的作用域与SqlSession对象相同,而SqlSession对象中又持有Executor对象,所以mybatis一级缓存的作用域也与Executor对象相同。mybatis的一级缓存功能模式是开启的。

createCacheKey

创建缓存的key,使用缓存模块的CacheKey对象来构建缓存的key。从下面的代码可以看出,缓存的key关注以下部分:

  • MappedStatement的ID
  • rowBounds对象的偏移量属性
  • rowBounds对象的limit属性
  • sql语句(带?占位符)
  • 用户传入的实参
  • Environment的ID属性

也就是说,如果上述6个部分都相同的话,则mybatis认为这是同一个对象

public CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql) {
   
  if (closed
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值