Mybatis 一级缓存和二级缓存

Mybatis

一. 前言
MyBatis是一个简单,小巧但功能非常强大的ORM开源框架,它的功能强大也体现在它的缓存机制上。MyBatis提供了一级缓存、二级缓存 这两个缓存机制,能够很好地处理和维护缓存,以提高系统的性能。本文的目的则是向读者详细介绍MyBatis的一级缓存,深入源码,解析MyBatis一级缓存的实现原理,并且针对一级缓存的特点提出了在实际使用过程中应该注意的事项。

一级缓存
Mybatis的一级缓存是指SQLSession,一级缓存的作用域是SQlSession, Mabits默认开启一级缓存。 在同一个SqlSession中,执行相同的SQL查询时;第一次会去查询数据库,并写在缓存中,第二次会直接从缓存中取。 当执行SQL时候两次查询中间发生了增删改的操作,则SQLSession的缓存会被清空。 每次查询会先去缓存中找,如果找不到,再去数据库查询,然后把结果写到缓存中。 Mybatis的内部缓存使用一个HashMap,key为hashcode+statementId+sql语句。Value为查询出来的结果集映射成的java对象。 SqlSession执行insert、update、delete等操作commit后会清空该SQLSession缓存。

二级缓存
二级缓存 二级缓存是mapper级别的,Mybatis默认是没有开启二级缓存的。 第一次调用mapper下的SQL去查询用户的信息,查询到的信息会存放代该mapper对应的二级缓存区域。 第二次调用namespace下的mapper映射文件中,相同的sql去查询用户信息,会去对应的二级缓存内取结果。

缓存原理图:
在这里插入图片描述
一级缓存(测试)
sqlSession级别的缓存。(相当于一个方法内的缓存)

每一次会话都对应自己的一级缓存,作用范围比较小,一旦会话关闭就查询不到了。
一级缓存默认是一直开启的,是SqlSession级别的一个Map。
与数据库同一次会话期间查询到的数据会放在本地缓存中。
以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库。

测试1:
在这里插入图片描述
结果1:在这里插入图片描述
测试2:
在这里插入图片描述
结果2:在这里插入图片描述
测试3:
在这里插入图片描述
结果3:在这里插入图片描述
测试4:在这里插入图片描述
结果4:在这里插入图片描述
看代码中的注释!!!

二级缓存
MyBatis 一级缓存最大的共享范围就是一个SqlSession内部,那么如果多个 SqlSession 需要共享缓存,则需要开启二级缓存,开启二级缓存后,会使用 CachingExecutor 装饰 Executor,进入一级缓存的查询流程前,先在CachingExecutor 进行二级缓存的查询,具体的工作流程如下所示在这里插入图片描述
当二级缓存开启后,同一个命名空间(namespace) 所有的操作语句,都影响着一个共同的 cache,也就是二级缓存被多个 SqlSession 共享,是一个全局的变量。当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。

开启二级缓存

在SqlMapConfig.xml中配置
在这里插入图片描述
来开启二级缓存,还需要在 Mapper 的xml 配置文件中加入cache标签
在这里插入图片描述

  1. eviction:缓存回收策略,有这几种回收策略
  •   -	LRU - 最近最少回收,移除最长时间不被使用的对象
    
  •   -	FIFO - 先进先出,按照缓存进入的顺序来移除它们
    
  •   -	SOFT - 软引用,移除基于垃圾回收器状态和软引用规则的对象
    
  •   -	WEAK - 弱引用,更积极的移除基于垃圾收集器和弱引用规则的对象
    
  1. flushinterval:缓存刷新间隔,缓存多长时间刷新一次,默认不清空,设置一个毫秒值 readOnly: 是否只读;true 只读,MyBatis 认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。MyBatis为了加快获取数据,直接就会将数据在缓存中的引用交给用户。不安全,速度快。读写(默认):MyBatis 觉得数据可能会被修改。
  2. size : 缓存存放多少个元素
  3. type: 指定自定义缓存的全类名(实现Cache 接口即可)
  4. blocking: 若缓存中找不到对应的key,是否会一直blocking,直到有对应的数据进入缓存。

二级缓存Java实体类必须使用序列化!!!
在这里插入图片描述

测试1:
在这里插入图片描述

在这里插入图片描述
结果1:
在这里插入图片描述
测试2:在这里插入图片描述
结果2:在这里插入图片描述
可以在SQL片段加的标签
在这里插入图片描述
在这里插入图片描述

是否应该使用二级缓存?
那么究竟应该不应该使用二级缓存呢?先来看一下二级缓存的注意事项:

1.缓存是以namespace为单位的,不同namespace下的操作互不影响。	
2.insert,update,delete操作会清空所在namespace下的全部缓存。 通常使用MyBatis
3.Generator生成的代码中,都是各个表独立的,每个表都有自己的namespace。
4.多表操作一定不要使用二级缓存,因为多表操作进行更新操作,一定会产生脏数据。

如果你遵守二级缓存的注意事项,那么你就可以使用二级缓存。

但是,如果不能使用多表操作,二级缓存不就可以用一级缓存来替换掉吗?而且二级缓存是表级缓存,开销大,没有一级缓存直接使用 HashMap 来存储的效率更高,所以二级缓存并不推荐使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值