蹲厕所的熊 转载请注明原创出处,谢谢!
Executor是Mybatis里面重要的一个接口,是4大对象(Executor、StatementHandler、ParameterHandler、ResultSetHandler)中的一个,下面我们先来看看Executor的继承关系图:
Mybatis默认启用了 ,它是用来做二级缓存的,但是如果没有配置 的话默认不启用二级缓存。它根据 来进行选择不同的 ,并在它内部维护了一个 的Executor对象,用它来执行真正的请求,说白了就是个装饰者模式。
那什么时候初始化Executor的呢?我们从SqlSessionFactory来看起。
每个sqlSession对应不同的Executor,在spring中,同一个事务里的sqlSession是相同的。
都重写了 的几个方法
下面我们来分析不同的Executor的实现细节
SimpleExecutor
源码其实很简单,每个方法几乎都分为以下几步:
获取配置
新创建一个statementHandler
准备statement
执行真正的查询、更新方法
ReuseExecutor
ReuseExecutor的实现其实和SimpleExecutor的类似,只不过内部维护了一个map来缓存statement
因为不同的sqlSession肯定有不同的executor,所以不同的executor即使有map缓存也没有作用。所以只有在同一个sqlSession的时候ReuseExecutor才有作用(在spring事务中可以使用,因为事务中是用的同一个sqlSession)。其他时候使用和SimpleExecutor无差别。
BatchExecutor
这个类从名字也知道它是用来进行批处理的,主要使用了jdbc的 以及 来执行批处理。
主要是把不同的Statement以及参数值缓存起来,在调用了 或 带有 注解的方法时,会调用 方法把数据批量刷新到表中。
在调用查询方法时,会首先刷新缓存的批量数据,再进行查询。
下面看看它的源码是如何实现的。
平时我没有使用过这种方式,都是直接在mapper文件中用for标签拼接字符串的方式来进行批处理,下面我们来做一个实验,对比一下谁的效率高。
下面是mapper接口以及对应的mapper.xml
前两个用batch的方式,一种1000个数据一提交(防止OOM),另一种1000个数据一flush,插入的时间都花了10秒左右,而用字符串组装的方式却只用了3秒。怪不得没人用BatchExecutor的方式呢。
不过如果你想在spring中使用,只需要进行简单的配置就可以了,这样我们就可以通过 或者 就可以进行同一个interface不同配置来使用了。
ClosedExecutor
这个类是 的内部类,外部没法使用,可以不用了解。
领取专属 10元无门槛券
私享最新 技术干货