Mybatis缓存机制

一、缓存机制介绍

1、缓存方式

Mybatis系统中默认定义了两级缓存:

分别是一级缓存和二级缓存

1、默认情况下只有一级缓存(SqlSession级别的缓存,也称为本地缓存)开启。

2、二级缓存需要手动开启和配置,它是记忆namespace级别的缓存。

3、为了提高扩展性,Mybatis定义了缓存接口Cache,我们可以通过实现Cache接口来自定义二级缓存。

2、一级缓存

  • 与数据库同一次会话期间查询到的数据会放到本地缓存中。
  • 以后如果要获取相同的数据,直接从缓存中拿,没必要再去数据库中去查了。
  • 一级缓存失效情况:还需要再向数据库发出查询。

      一级缓存失效情况如下:

        1、SqlSession不同

        2、SqlSession相同,查询条件不同(当前一级缓存中还没有这个数据)。

        3、SqlSession相同,两次查询之间执行了增删改操作(这次增删改可能对当前的数据有影响)

        SqlSession相同,手动清除了一级缓存(缓存清空)

2、二级缓存

属于全局缓存,基于namespace名称空间级别的缓存,一个namespace对应一个二级缓存。

工作机制:

1、一个会话,查询一条数据,这个数据就会被放在当前会话的一级缓存中。

2、如果会话关闭,一级缓存中的数据会保存到二级缓存中,新的会话查询信息,就可以参照二级缓存的内容。

3、不同namespace查出的数据会放在自己对应的缓存中(map)中。

4、只有会话提交或者关闭以后,一级缓存中的数据才会转移到二级缓存中去

(1)、二级缓存的使用

第一步:开启全局二级缓存配置

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

第二步:去mapper.xml中配置使用二级缓存

<cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024" type="">
</cache>

size:缓存存放多少元素
type: 指定自定义缓存的全类名----实现cache接口即可

参数解析:

第三步:POJO需要实现序列化接口

3、缓存的一些设置规则

  • cacheEnabled设置为false,关闭缓存,这时候关闭的是二级缓存,一级缓存不会被关闭。
  • 每个select标签都有useCache="true"设置,设置为false:不使用缓存(关闭的是二级,一级正常用)。
  • 每个增删改查标签的flushCache="true",表示增删改查执行完成后就会清空缓存(一级二级都会被清空).
  • sqlSession.clearCache();只清空当前session的一级缓存

4、缓存的原理图

5、缓存顺序

二级缓存---->一级缓存----->数据库

6、融入第三方缓存进来,只要实现cache接口就可以

第三方缓存比较主流是:EhCache,需要pom文件中引入EhCachejar包

<cache  type="EhCache自定义类"></cache>

 

7、spring与mybatis整合后一级缓存失效问题解析

spring结合mybatis后,一级缓存作用:

在未开启事务的情况之下,每次查询,spring都会关闭旧的sqlSession而创建新的sqlSession,因此此时的一级缓存是不起作用的
在开启事务的情况之下,spring使用ThreadLocal获取当前资源绑定同一个sqlSession,因此此时一级缓存是有效的。
mybatis的一级缓存是基于session来的,当单独使用mybatis的时候,一级缓存是起作用的,在一个session中查询2遍同样的sql,只会打印一次sql语句。但当mybatis与spring搭配使用后,mybatis的一级缓存就会失效,会打印2次sql。

一级缓存失效原因:mybatis和spring结合使用的时候,将原本的DefaultSqlSession替换成了SqlSessionTemplate,并且在SqlSessionTemplate将sqlSession替换成了sqlSessionProxy代理对象,当我们执行sqlSession的方法的时会调用到SqlSessionInterceptor的invoke()方法, 在invoke()方法的fianlly中调用了SqlSessionUtils.closeSqlSession()方法将SqlSession关闭了,所以一级缓存就会失效了。

也就是说,spring对mybatis的SqlSession的使用是由SqlSessionTemplate控制的,在SqlSessionTemplate类中执行SQL语句的SqlSession都是通过sqlSessionProxy来代理执行的,sqlSessionProxy的生成是在构造函数中赋值
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值