MyBatis缓存机制之一级缓存
创始人
2024-02-19 11:03:50
0

MyBatis缓存机制之一级缓存

前言

        MyBatis内部封装了JDBC,简化了加载驱动、创建连接、创建statement等繁杂的过程,是我们常见的持久性框架。缓存是在计算机内存中保存的临时数据,读取时无需再从磁盘中读取,从而减少数据库的查询次数,提高执行效率。Mybatis提供了一级缓存和二级缓存的支持,默认情况下只开启一级缓存。本次将带着大家深入了解Mybatis的一级缓存机制。

介绍

        当我们访问数据库时,Mybatis会创建出一个SqlSession对象开启一次数据库会话。在这次会话中,我们可能会执行多次相同的查询语句,如果不采取措施,每一次查询都会访问数据库,造成资源的浪费。为了优化这部分场景,Mybatis提供了一级缓存的方案,如果是相同的SQL语句,会优先命中一级缓存,避免直接对数据库进行查询。具体执行过程如下图所示。

         每个SqlSession中都持有Executor执行器,每个Excutor中有一个LocalCache缓存。Mybatis根据当前执行的SQL生产MappedStatement,在缓存中进行查询,如果缓存命中的话,直接返回结果给用户,如果缓存没有命中,查询数据库,结果写入LocalCache,再返回结果给用户。具体实现类的类关系图如下所示:

 

源码分析

我们将对MyBatis的源码进行分析,深入理解底层原理。

        SqlSession: SqlSession是应用程序与持久层执行交互操作的单线程对象,代表着一个资源的启用,包含所有执行SQL操作的方法。默认实现类是DefaultSqlSession。

        主要作用:1、获取Mapper接口;2、发送SQL给数据库;3、控制数据库事务

         Executor执行器:Executor定义了查询、更新、事务、缓存操作相关的接口方法,由SqlSession依赖,并受其调度与管理。核心功能是调度执行SQL。在Executor内部完成对LocalCache的查询和写入。

 

 Cache:Mybatis中的Cache接口,提供了缓存的基本操作。

         PerpetualCache是对Cache接口最基本的实现,其原理非常简单,内部持有HashMap,对一级缓存的操作实则是对HashMap的操作。如下代码所示:

        客户端与数据库的交互,首先通过DefaultSqlSessionFactory开启SqlSession:

                 在初始化SqlSession时,会通过configuration类创建一个新的Executor:

         SqlSession创建完毕后,根据不同类型的Statement,SqlSession会执行对应的方法。比如Select语句,最终会执行到selectList方法

        SqlSession把具体的查询交给Executor去执行。如果只开启了一级缓存的话,首先会进入BaseExecutor的query方法。代码如下所示:

        会根据传入的参数生成CacheKey作为唯一标识,进入方法,查看具体的生成逻辑:

        在上述的代码中,将MappedStatement的Id、SQL的offset、SQL的limit、SQL本身以及SQL中的参数传入了CacheKey这个类,最终构成CacheKey。在CacheKey的update方法中,会进行一个hashcode和checksum的计算,同时把传入的参数添加进updatelist中。如下代码所示:

 只要两条SQL的下列五个值相同,即可以认为是相同的SQL。

Statement Id + Offset + Limmit + Sql + Params

如果在LocalCache查不到的话,就会查询数据库,并将结果写入至缓存。

         如果是insert/update/delete方法,统一都会走SqlSession的update流程,同样委托执行器执行SQL。

        执行方法如下,我们可以发现每次执行update前都会清空LocalCache。所以当发生修改操作时,一级缓存会失效,防止了数据脏读。

 总结

1、一级缓存LocalCache只是BaseExecutor的一个字段。所以,当SqlSession的生命周期结束时,一级缓存也会被回收。

2、一级缓存由PerpetualCache实现,其内部通过HashMap完成对缓存的读写操作,所以本质上讲,一级缓存其实是通过HashMap实现的,Map中的key是由MappedStatement生成CacheKey,来确保查询的唯一性。

3、MyBatis的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,数据库写操作会引起脏数据,建议设定缓存级别为Statement。

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
苏州离哪个飞机场近(苏州离哪个... 本篇文章极速百科小编给大家谈谈苏州离哪个飞机场近,以及苏州离哪个飞机场近点对应的知识点,希望对各位有...
客厅放八骏马摆件可以吗(家里摆... 今天给各位分享客厅放八骏马摆件可以吗的知识,其中也会对家里摆八骏马摆件好吗进行解释,如果能碰巧解决你...