MyBatis从会话到执行器再到一级缓存

MyBatis 越过Mapper动态代理–从会话到执行器的逻辑初次梳理

JDBC 执行过程

获取连接–》预编译SQL–》设置参数–》执行SQL

三种操作数据库的statement

  1. 简单执行器 Statement

  2. 预处理执行器 Prepared Statement 防注入

  3. 存储过程执行器 Callable Statement
    在这里插入图片描述

MyBatis 执行体系 (主流程)

​ 一、 sqlSession 对应的功能有提交会话和关闭会话。因为不能保证线程安全,所以不能跨线程调用。

​ 只提供会话,不执行操作,具体操作交给执行器Executor

​ 二、Executor 基本功能 改、查 、维护缓存 辅助功能 提交、关闭执行器 刷新批处理

​ 三、Statement Handler 是对jdbc 参数设置、结果处理的具体处理

注意:一个sqlsession会话 对应一个executor,一个executor对应多个StatementHandler
在这里插入图片描述

三种执行器

在这里插入图片描述

默认使用的执行器为SimpleExcutor

BaseExcutor、CachingExecutor、SimpleExcutor、ReuseExecutor、BatchExecutor

其中CachingExecutor(二级缓存执行器) 是通过装饰器模式添加,对应的功能包括缓存处理、事务处理、

重用处理以及批处理,这些共性是在同一个会话中多个SQL执行才具有的

SimpleExcutor:每次处理都会创建一个新的预处理器(PrepareStatement)

ReuseExecutor: 相同的SQL只进行一次预处理

BatchExecutor:批处理提交修改必须执行flushStatements才能生效

三种(SimpleExcutor、ReuseExecutor、BatchExecutor)执行器的区别与互通点

​ 一、都是继承了BaseExecutor抽象类,目的是为了实现MyBatis的一级缓存的实现

​ 二、都对应三种Statement(Statement、PrepareStatement、CallableStatement)

​ 也就是对应的对应数据库的三次不同的交互模式(

​ 1、Statement:每次发送一条静态SQL

​ 2、PrepareStatement:发送一次SQL多次参数,因为具有预编译的方式

​ 3、CallableStatement:发送一次 传输多条SQL和多个参数,之针对修改有效)

​ 三、SimpleExcutor 执行静态SQL、批处理、设置加载的行数范围BoundRow

​ 四、针对与JDBC的Statement对于相同的sqlsession会话,三种执行器调用不同的

​ 的方法,最后编译相同的SQL都会在使用相同的Statement

BatchExcutor 批处理提交对应的session

JDBC 的Statement 在 sqlsession、MapperStatement、执行的SQL是连续的就会使用相同的Statement

基础执行器与一级缓存

一级缓存在BaseExcutor中执行

1、命中场景–默认打开

		运行时参数相关
		1、SQL和参数相同    命中一级缓存
		2、相同的StatementID(全定限名点方法)-----》对应的相同的Mapper接口定义的方法名不同
   		3、sqlSession 必须相同
        4、RowBounds 相同 (返回值行数范围)
        操作与配置相关
        1、未手动清空
        2、未调用 flushCache=true 的查询
        3、未执行Update
        4、缓存作用域不是STATEMNET-->嵌套查询   对应改的属性localcachescope

2、会话缓存清空位置

​ 手动flushCache清空、配置flushCache=true、执行Update操作、

​ 全局配置localcachescope属性STATEMENT

​ 针对修改update操作时,会将当前会话的所有的缓存都清空! 因为会话的生命周期是短暂的,所 以没必要针对于修改的部分进行清空,直接全部清空当前会话的缓存也就是一级缓存。

class BaseExcutor implements Executor {
  	
  protected PerpetualCache localCache;
  
  //.....
  
  @Override
  public int update(MappedStatement ms, Object parameter) throws SQLException {
    ErrorContext.instance().resource(ms.getResource())
      .activity("executing an update").object(ms.getId());
    if (closed) {
      throw new ExecutorException("Executor was closed.");
    }
    clearLocalCache();
    return doUpdate(ms, parameter);
  }
  
  //.....
  
  @Override
  public void clearLocalCache() {
    if (!closed) {
      localCache.clear();//执行缓存清除操作
      localOutputParameterCache.clear();
    }
  }
  
}	


//缓存类
public class PerpetualCache implements Cache {

  private Map<Object, Object> cache = new HashMap<>();
	
  @Override
  public void clear() {
    cache.clear();
  }
  
}


最后结合执行器的缓存总体流程
在这里插入图片描述

如有错误地方,欢迎大家指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值