MyBatis之缓存机制


一级缓存(本地缓存)

sqlSession级别的缓存。(相当于一个方法内的缓存)

每一次会话都对应自己的一级缓存,作用范围比较小,一旦会话关闭就查询不到了;

一级缓存默认是一直开启的,是SqlSession级别的一个Map;

与数据库同一次会话期间查询到的数据会放在本地缓存中。

以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库;


一级缓存维护在哪里


DefaultSqlSession中只有两个属性可能存放缓存

1)private final Configuration configuration;(全局的,不可能)

2)private final Executor executor;(有可能)



一级缓存什么时候被清空?

从源码可知:在执行update、insert、delete、flushCache="true"、commit、rollback、LocalCacheScope.STATEMENT等情况下,一级缓存就都会被清空。







一级缓存key是什么 ,怎样创建?

Executor接口方法  createCacheKey()

key的生成策略:id + offset + limit + sql + param value + environment id,这些值都相同,生成的key就相同



二级缓存如何开启?



 使用:

*             1)、开启全局二级缓存配置:

*             2)、去mapper.xml中配置使用二级缓存:

*                 

*             3)、我们的POJO需要实现序列化接口

二级缓存key是什么 ,怎样创建?

与一级一样


是否应该使用二级缓存?

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

1. 缓存是以namespace为单位的,不同namespace下的操作互不影响。

2. insert,update,delete操作会清空所在namespace下的全部缓存。

3. 通常使用MyBatis Generator生成的代码中,都是各个表独立的,每个表都有自己的namespace。

4. 多表操作一定不要使用二级缓存,因为多表操作进行更新操作,一定会产生脏数据。

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

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

5. 多表操作对二级缓存的影响 的解决办法,采用 cache-ref 来进行命名空间的依赖能够避免二级缓存,但是总不能每次写一个 XML 配置都会采用这种方式吧,最有效的方式还是避免多表操作使用二级缓存

工作机制:

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

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

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

*             效果:数据会从二级缓存中获取

*                 查出的数据都会被默认先放在一级缓存中。

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



和缓存(一二级)有关的设置/属性

1)、mybatis全局配置文件中配置全局缓存开启和清空

2)mapper.xml中也可以配置一级和二级缓存开启和使用

你可能感兴趣的:(MyBatis之缓存机制)