开发者学堂课程【高校精品课-厦门大学 -JavaEE 平台技术:Executor接口】学习笔记,与课程紧密联系,让用户快速学习知识
课程地址:https://developer.aliyun.com/learning/course/80/detail/15947
Executor接口
浅蓝色的部分是它的 Executor。
我们在执行一个 SqlSession 命令的时候,比如执行一个 intor命令,它执行的过程并不是在 SqlSession执行的,而是靠放入的 Executor执行的,Executor 是SqlSession 的一个属性。
它为什么不让自己执行呢?因为执行的时候它有多种的选择,所以我们看见在Executor里面有实现的多个子类。它有几种执行方式,最简单的就是SimpleExecutor,就是给它什么它执行什么。SimpleExecutor 实现了本地一级缓存,所以我们看到它的一级缓存是在父类上面的。它所有的子类都有
BaseExecutor,所以无论用什么样的方式去执行都有一级缓存,就是这个黄色的部分。
缓存部分其实还有很多的类,没有全部画出来,这里只画了一个它有缓存的。既然有缓存就会有很多其他的问题:比如缓存满了怎么办?当你在 put的时候,如果缓存满了就需要把一些东西淘汰出去,所以关于缓存怎么处理是有一系列装饰器的设
计模式来装饰这个 Cache,但这不是我们要讨论的重点。
它在 BaseExecutor就做了一级缓存,一级缓存是关不掉的,因为它存在
BaseExecutor 里面,只要你去用,它都会试图把在同一次执行过程中间查过的数据存在这个LocalCache里面。
在MyBatis中间最简单的就是 SimpleExecutor,带一级缓存的、执行一条的一个语句,除了SimpleExecutor以外,还有一个 ReuseExecutor,它可以做到绘画级的缓
存,就是在一个 SqlSession中间,如果你有查过的话就会把它存下来。
它存的方式不是存结果,而是存 statement,就是把它编译过的存下来,所有语句在执行前都需要做预编译、Prepass,是需要时间的,那 ReuseExecutor可以把所有执行过的、预编译好的结果存下来,这样就可以直接拿预编译好的 Statement去
做执行,而不需要再做 Prepare的过程了,这就是 ReuseExecutor。
BatchExecuto r是 Mybatis中做批量处理的,在一个 SQL的定义中间是可以执行多条SQL语句的,那此时需要用 BatchExecutor来执行。
CachingExecutor 是什么呢?首先它是一个Executor,但关键是它里面还有一个属性叫做 delegate,指向了 BaseExecutor,那意味着我们可以把一个SimpleExecutor 放到 CachingExecutor里面,或者把 ReuseExecutor放到CachingExecuto r里面,或者把批量的 Executor放到 CachingExecutor里面。这样放进来的作用就是这个 CachingExecutor可以在 Executor的基础上面,比如单个查询、做可缓存的预编译的查询,或者做批量查询的基础上能够加一个二级缓存。一级缓存已经天然存在,因为所有的都继承父类,所以它一定有一级缓存,而这个是为了去做二级缓存。二级缓存是在默认的一台服务器上的,不管谁去访问过 SQL语
句,只要在一个 Namespace的范畴之内就会去做缓存。
所以说在服务器运行起来以后,同样的查询不会出现两次是靠 CachingExecutor来完成的,所以 CachingExecutor里面会存在一个缓存,而这个缓存会把之前查过的
结果放在里面。
所以当 SqlSession要做任何一个命令的时候,它首先去看 CachingExecutor里面的缓存是否有,如果有,它就会直接返回;如果没有,才会去执行它里头所放的
Executor,或者是 SimpleExecutor或者是 ReuseExecutor,去真正去做执行。
而这个 Executor也有一个缓存,就是它的一级缓存,如果它有一级缓存,就有可能一级缓存返回;如果没有,它就会就是查询,查询完后本身的SimpleExecutor把会它放到一级缓存里,回到 CachingExecutor后会把它放到二级缓存里面,最后才返回。所以这样的方式就是我们的一个设计模式,叫做代理模式,就是我们并不直接使用提供的三种 Executor,而是在三种 Executor上面做了一个代理的 Executor,叫做 CachingExecutor,所以它的属性文件的代理就叫Delegate,那它是在其代理的 Executor上做了一些增强,现在的增强是做二级缓存,我们所有的设计模式都可以用一个方法去做分析,分析一个设计它的好处在哪、让我们知道 Mybatis是一个
非常经典的设计,它也是所有的用到设计模式的地方,都是无可挑剔的。
比如分析这个地方它用的设计模式来实现这个目的,首先分析说要达成什么样的目的,然后再去想它是用什么样的手段来达成这样的目的。它首先要达成目的就是,它不想让其他的部分代码知道我使用了一个代理,我用代理或者不用代理,就是我用 CachingExecutor或不用 CachingExecutor,对于所有其他部分的代码都不会受到影响,这意味着二级缓存是可以开关的,我开二级缓存或者关二级缓存,所有代
码的执行路径都是一样的,除了在它开二级缓存这一段,也就是 CachingExecutor
的这一段是不一样的以外,其他的地方都是完全一样。
它怎样使得这个代理存在和不存在都不会影响到其他部分的代码的的呢?
最主要的手段就是降低它跟其他部分的耦合,而降低耦合的一个重要的手段就是用
多态,所以可以看到这里有一个继承关系。
这个继承关系不是因为 BaseExecutor,因为大家用的都是 Executor,所以在SqlSession 放的是一个类型的对象,这个对象有可能是SimpleExecutor、
ReuseExecutor、CachingExecutor、BaseExecutor,但无论是哪一个对象,对于SqlSession来说是没关系的,所以这样的一个代理机制放在这个地方所起的作用就是让这个代理的对象跟其它的三个对象是一致的。
因为都实现了同样的一个接口,所以换个代理对象进去或者换个其它对象进去是没
有任何差别的,这就是代理的机制。