深入学习mybatis(一) Executor 执行器
mybatis 执行流程
从图中可以看出大部分业务逻辑主要都在Executor 中得到执行。下面将详细梳理一下Executor的结构。
Executor 执行器
Executor 是mybatis 执行sql的接口。所有的增删改查,以及其他操作,最终都会由Executor 来执行。它功能主要包括
- 基本功能: 增,删,改,查
- 缓存维护: 执行器Executor 主要维护的是1级缓存服务,主要包括创建缓存,清理缓存,判断缓存是否存在
- 事务管理: 事务提交,回滚,关闭,批处理更新
Executor的实现类
- SimpleExecutor 简单执行器
SimpleExecutor 是默认的执行器,它的特点是在一次会话中,每次处理sql的时候,在进过StatementHandler 都会构建一个新的Statement,会导致即使相同的sql也无法重用Statement。
- ReuseExecutor 重用执行器
ResueExecutor区别在于它会将在会话期间内的Statement 进行缓存,并使用sql语句作为key,在执行下一次请求的时候,如果sql完全相同,直接拿出statement 进行执行。与简单执行器的区别就是,对statement进行缓存,如果是相同的sql,则复用statement。
- BatchExecutor 批处理执行器
BatchExecutor 用做批处理,会将所有的sql请求几种起来,最后在调用Executor.flushStatements()方法时,一次性将所有请求发送至数据库。
BaseExecutor
Executor 除了 执行基本的功能,还有维护缓存,缓存对于以上几种执行器来说,属于是公共逻辑,所有对以上三种执行器,抽象出BaseExecutor 来进行缓存(一级缓存)的维护。当执行sql的时候,先看缓存中是否存在,如果存在,则从缓存中直接取出结果,如果不存在,则再调用对应执行器的doQuery()方法查询。并将查询结果设备到缓存中。
缓存执行器CacheExecutor(二级缓存)
BaseExecutor 维护了一级缓存,当然mybatis还有一个二级缓存,我们可以通过配置关闭或者打开。因为二级缓存和一级缓存逻辑相对独立,所以将其单独抽象出来进行处理。抽取方式使用了装饰器模式,CachingExecutor 对原有执行器进行包装,处理完二级缓存之后,在将逻辑交给Executor处理
小结
mybatis的一次查询的sql操作(开启二级缓存,并且第一次查询的时候), 在Executor模块会经过以下几步
- step1: 先到了CachingExecutor 在二级缓存是否存在。存在则返回,不存在,则传递给baseExecutor
- step2: baseExecutor 在收到来之CachingExecutor的请求之后,判断查询结果是否在1级缓存中,如果缓存中存在,则直接返回,否则,调用(SimpleExecutor/ReuseExecutor/BatchExecutor) 进行数据库查询,并将查询结果缓存到1级缓存中。返回结果给CachingExecutor
- step3: CachingExecutor 收到BaseExecutor 返回结果,将结果添加到二级缓存中。
之前有遇到过在项目启动之后,手动修改数据库,再去调用接口查询,结果查询到的值还是原来的旧的值,需要重启项目,原来是缓存搞得鬼!! 哈哈哈哈!