Mybatis源码分析(四)执行器和缓存
前面说过mybatis是靠Executor来执行sql的,Executor的类型又分了三种。
public enum ExecutorType { SIMPLE, REUSE, BATCH }
默认是SIMPLE这一种。可以在全局配置文件中通过下面配置改变
<settings> <setting name="defaultExecutorType" value="BATCH"/> </settings>
至于他们有什么不同,看下源码就晓得了。对比同一个方法:
SimpleExecutor#doQuery
ReuseExecutor#doQuery
BatchExecutor#doUpdate
从上面三种类型对于statement的处理可以知道:
ExecutorType.SIMPLE:这个执行器类型不做特殊的事情。它为每个语句的每次执行创建一 个新的预处理语句。
ExecutorType.REUSE:这个执行器类型会复用预处理语句。
ExecutorType.BATCH:这个执行器会批量执行所有更新语句,也就是jdbc addBatch API的 facade模式。
缓存机制
mybatis提供了基本实现org.apache.ibatis.cache.impl.PerpetualCache,内部采用原始 HashMap实现。第二个需要知道的方面是mybatis有一级缓存和二级缓存。一级缓存是 SqlSession级别的缓存,不同SqlSession之间的缓存数据区域(HashMap)是互相不影 响,MyBatis默认支持一级缓存,不需要任何的配置,默认情况下(一级缓存的有效范围可 通过参数localCacheScope参数修改,取值为SESSION或者STATEMENT),在一个 SqlSession的查询期间,只要没有发生commit/rollback或者调用close()方法,那么 mybatis就会先根据当前执行语句的CacheKey到一级缓存中查找,如果找到了就直接返 回,不到数据库中执行。其实现在代码BaseExecutor.query()中。
一级缓存
mybatis提供了基本实现org.apache.ibatis.cache.impl.PerpetualCache,内部采用原始 HashMap实现。第二个需要知道的方面是mybatis有一级缓存和二级缓存。一级缓存是 SqlSession级别的缓存,不同SqlSession之间的缓存数据区域(HashMap)是互相不影 响,MyBatis默认支持一级缓存,不需要任何的配置,默认情况下(一级缓存的有效范围可 通过参数localCacheScope参数修改,取值为SESSION或者STATEMENT),在一个 SqlSession的查询期间,只要没有发生commit/rollback或者调用close()方法,那么 mybatis就会先根据当前执行语句的CacheKey到一级缓存中查找,如果找到了就直接返 回,不到数据库中执行。其实现在代码BaseExecutor.query()中。
org.apache.ibatis.executor.BaseExecutor#createCacheKey 4个字段 Map<cachekey,list>
二级缓存:
二级缓存指的就是同一个namespace下的mapper,二级缓存中,也有一个map结构,这 个区域就是一级缓存区域。一级缓存中的key是由sql语句、条件、statement等信息组成一 个唯一值。一级缓存中的value,就是查询出的结果对象。
开启缓存:
<settings> <setting name="cacheEnabled" value="true"/> </settings>
设置二级缓存:
<mapper namespace="org.mybatis.example.BlogMapper"> <cache></cache> <select id="cacheBlog" resultType="bat.ke.qq.com.pojo.Blog"> select * from Blog where id = #{id} </select>
如果某个select不想用缓存的话可以设置:useCache=false flashcache=true不用缓存
具体继承关系:
cache-ref引用二级缓存
<mapper namespace="xxxx.Mapper1"> <!‐‐ Mapper1 与 Mapper2 共用一个二级缓存 ‐‐> <cache‐ref namespace="xxxx.Mapper2"/>
一般二级缓存也不会开启使用
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现