深入理解mybatis的二级缓存

mybatis分为一级缓存和二级缓存。

mybatis默认开启一级缓存。

如何解析:

执行者:XmlConfiguraBuilder类 

解析对象:mybatis所有的配置信息

目标:Configuration(包含数据源、事务、mapper等的配置的对象)

sqlSession是什么:

mybatis的关键对象,也是一级缓存的作用域,

相当于JDBC的Connection,底层封装了JDBC连接,通过它操作数据库。

线程不安全的,不能被共享。

一级缓存(sqlSession级别):

实现:

Executor 1.构造cacheKey去PerpectualCache中去查询对应的结果value

2.没有,就去数据库中去查,将查询结果保存到PerpectualCache中,然后再返回。

备注:

一级缓存实际上是使用PerpetualCache来维护的,内部使用一个HashMap,

key(cacheKey)为hashcode+statementId+sql语句。Value为查询出来的结果集映射成的java对象。

当ddl的时候会清空sqlSession的缓存。

看图理解:

二级缓存(Mapper级别):

实现:

Executor 1. Executor 的装饰者CachingExecutor去二级缓存查

2.没有,就让真正的Executor去一级缓存去查。

注:每个Mapper有一个Cache,多个Mapper可以通过cache-ref公用一个Cache 

看图理解:

二级缓存实现方式:

1.Mybatis自身提供

2.自定义Cache接口

3.第三方中间件

开启二级缓存:

1.Mybatis的配置文件SqlMapConfig.xml 中设置cacheEnabled为true;

2.Mapper.xml中设置Cache

3.select中配置useCache为true(默认为true)

4.映射的实体类需要序列化:

理由:由于二级缓存的数据不一定都是存储到内存中,它的存储介质多种多样,所以需要给缓存的对象执行序列化。

二级缓存存在的问题:

A,B二表联合查询,

结果放到MapperA的cache中(其中有B表此时的数据哦),

然后有对B表的update操作,会清空MapperB的cache,

但此时无法将MapperA中cache实时更新。

最佳解决方案:

Enhanced-Cache来管理缓存。

猜你喜欢

转载自blog.csdn.net/zhangyu672090/article/details/82805615