Mybatis基础 (1) 一二级缓存

前言

(1)Mybatis概念
(2)Mybatis一二级缓存的配置以及基本的使用
(3)Mybatis一二级缓存的工作流程以及源码分析

目录

1 Mybatis基础概念介绍
2 一级缓存相应资源配置
3 一级缓存工作流程以及源码分析
4 一级缓存系统总结
5 二级缓存相关配置介绍
6 二级缓存源码分析
7 二级缓存总结
8 Mybatis 缓存机制优缺点分析(缓存机制总结)

==============================================
Let’s GO!

==============================================
Mybatis基础概念:

所谓的MyBatis就是支持定制化的SQL,存贮过程以及高级的映射的优秀持久层框架。
Mybatis几乎避免了所有的JDBC需要进行的手动配置参数以及获取结果集。
Mybatis可以支持配置原生的Map以及简单的XML注解的支持。可以将接口和Java的POJO来进行映射为数据库的记录。

Mybatis中的几个核心概念讲解:
1 sqlsession :代表与数据库进行的一次会话,提供了操作数据库的基本接口和方法。
2 MappedStatement:这个指的就是SQL发的指令,简单理解的话就是SQL语句抽象表示。
3 Executor:用来和数据库交互的执行器,接收参数MappedStatement。
4 映射接口:指代的就是要执行的SQL,这里的话通常用一个抽象的方法来进行表示。
5 映射文件: 理解为Mybatis编写SQL的地方。通常的情况之下每张表都会有对应的映射文件。在文件中通常会定义SQL的入参还有出参。

实例展示:
应用一个实际的Student类来进行举例子,通常进行多表查询的时候会将查询的方法定义在一个StudentMapper之中供使用,也可以将多表的查询语句进行抽取之后放到一个独立的接口文件之中,通常开发的角度来讲会定义相应的sql映射文件主要由相应的mapper文件以及相应的select|delete|update|insert等基本操作。

在这里插入图片描述
一级缓存概念基础介绍:
日常使用背景:通常情况下,在实际的SQL会话中一定会存在这样的情况,就是在一次的SQL会话中,会执行多次的查询条件完全相同的SQL,大部分的应用场景都是读多写少,这种重复的查询工作会对系统有一定的开销。尤其是数据量很大的情况之下对系统的性能影响是非常大的。

因此Mybatis提供了一级缓存的优化方案,来解决重复性比较高的查询SQL问题,具体的实现方式是在每个SQLsession中都持有了自己的缓存。
(1)session级别缓存:就是在一个Mybatis的会话中,会执行所有的SQL语句。完后进行共享这个会话。
(2)statement级别:缓存只对当前的statement有效;
sqlsession缓存机制
(1)这个简单理解的话就是每个的SQLsession都会有自己的executor,
(2)而且每个executor都有自己本身的local cache ,
(3)当用户去查询的过程中Mybatis会根据当前的MappedStatement生成的Key
(4)去自己本省的local cache进行查询,如果命中的话,直接返回结果。
(5)没有命中的话。将本次查询的写入local cache之中,完后进行返回当前的结果集。

一级缓存配置
Mybatis的一级缓存的配置比较简单,只需要在Mybatis的配置文件中添加如下的配置就可以实现:
配置的级别有两种;session 和 statement 默认的级别是session

<setting name="localCacheScope" value="session">

此处省略若干字 待更新

在这里插入图片描述在这里插入图片描述在这里插入图片描述
结论:只有第一次查询的是走数据库查询的数据,其他全部走的是cache.
同级试验,在一次的数据库的多次相同的检索中之间插入了修改操作发现一级缓存会失效。而且一级缓存只在单个的sqlsession内部共享,会出现脏数据的情况。

注意的点:一级缓存只限于数据库会话内部共享;

Mybatis以及数据库缓存工作流程:
(1)对于确定的select 语句查询到的结果集,会生成一个key值;
(2)判断在localcache中,该key值是否有相应的数据存在;
(3)如果命中,跳过查询数据库操作,直接进入下一环;
(4)如果没命中:
1)去数据库查询数据完后得到相应的查询结果。
2)将key以及查询的结果 作为key和value 存贮在local cache中。
3)完后将查询的结果进行返回。
(5)判断缓存级别,如果为statement级别的话,清空本地缓存。

Mybatis 缓存源码分析:
(1)BaseExcutetor:BaseExecutor 是executor的一个抽象的接口,而在具体业务调用的时候会将相应的业务交给自己的子类进行执行。
(2)在一级缓存对localcache的缓存其实是在executor内部进行的,通过阅读源码也可以进行发觉,此时的Local cache 就是本地的一个成员变量。
(3)关于缓存的cache:Mybatis本地的cache之中,提供了有关于缓存的基本操作,由若干个实现类,使用的装饰者模式进行的相互组装进行实现的,从而提供了丰富的操控缓存的能力。
在这里插入图片描述
(4)相比之下的BaseExecutor成员变量之一就是perpetualCache,简单理解的话就是对cache的最基本的实现。实现原理就是内部持有了hashmap,总结性的来讲一级缓存就是对这个hashmap的基本操作。
在这里插入图片描述
源码分析过程待更新:
在这里插入图片描述

此处省略若干字。。。敬请更新中

缓存机制小结:
(1)Mybatis的一级的缓存生命周期和SQL session的生命周期是一致的;
(2)Mybatis是一个粗粒度的缓存机制,没有更新缓存以及缓存过期的概念,同时默认上只是使用了hashmap 在具体的容量上也没有做相应的限制。
(3)Mybatis的缓存机制最大的范围就是SQL session的内部,当有多个session或者分布式的情况下,有操作数据库的读写的话会有相应的脏数据情况出现。比较安全的advice是开启的级别设置为statement ,简单总结下就是 不用一级缓存。

二级缓存机制介绍:
如同上文所介绍的那样,一级缓存能解决的问题是在当前的SQL session之中进行数据共享,如果多个的SQL session之间的数据进行共享的话那么该如何进行实现呢。答案就是二级缓存。
当开启二级缓存机制的时候,会使用cacheingExecutor来进行装饰Executor,在进行后续CachingExecutor执行前会进行二级缓存查询。具体执行的流程图如下:

二级缓存流程图 暂时省略

在二级缓存执行的过程中,一个namespace之下的所有操作语句,都只影响一个Cache,总结性来讲的话,就是二级缓存是个全局变量可以在多个SQL session中进行共享。

当开启缓存机制之后,基本的执行顺序是:二级缓存---->一级缓存----->数据库

二级缓存基本配置:
(1)二级缓存的配置如下:

<setting name="cacheEnabled" value="true"/>

(2)Mybatis映射XML之中配置cache 或者 cache-ref

<cache-ref namespac=''mapper.stuentMapper'/>

以上标签代表的是命名空间的cache分配机制,两个命名空间的操作用的是相同的cache.

<cache/>

采用 mybatis 内置的 cache 机制。
在 sql 语句映射文件中加入 语句 , 并且相应的 model 类要实现 java Serializable 接口,因为缓存说白了就是序列化与反序列化的过程,所以需要实现这个接口. 单纯的 表示如下意思:
1.所有在映射文件里的 select 语句都将被缓存。
2.所有在映射文件里 insert,update 和 delete 语句会清空缓存。
3.缓存使用“最近很少使用”算法来回收
4.缓存不会被设定的时间所清空。
5.每个缓存可以存储 1024 个列表或对象的引用(不管查询出来的结果是什么) 。
6.缓存将作为“读/写”缓存,意味着获取的对象不是共享的且对调用者是安全的。不会有其它的调用者或线程潜在修改。


cache标签用于声明这个namespace 使用二级缓存,并且支持自定义配置。
*type:cache使用的类型,默认的是perpetualCache。
*eviction:定义回收策略,常见的有FIFO,LRU
*flushIntern:配置一定的时间进行自动刷新缓存常见的配置是毫秒级;
*size:最多的缓存数量;
*readonly:是否可读,进行配置是否可以进行读写,需要进行对应实体进行序列化;
*bloking:若缓存没有命中的情况下,是否会一直进行blocking,直到有数据库进入缓存。

猜你喜欢

转载自blog.csdn.net/qq_37779333/article/details/84302245