SpringBoot下mybatis-一级、二级缓存测试及总结

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

一、默认开启一级缓存。一级缓存是 SqlSession 级别的。

具体什么意思测试一下。

一次事务中,同一语句调用两次,代码:

VarDateEntity varDateEntity = dateMapper.getVarDate();

System.out.println("var1 var:"+varDateEntity.getVarTime());

System.out.println("var1 not:"+varDateEntity.getNotTime());

System.out.println("var1 null:"+varDateEntity.getNullTime());

varDateEntity = dateMapper.getVarDate();

System.out.println("var2 var:"+varDateEntity.getVarTime());

System.out.println("var2 not:"+varDateEntity.getNotTime());

System.out.println("var2 null:"+varDateEntity.getNullTime());

Postman 中执行两次:

测试结果:

结论1:

同一事务中的两次查询,只查询了一次。但是两次事务中,每次均进行了一次查询;

一级缓存的 scope 默认值session;

设置为:statment 。重启 springboot 应用再次测试:

结论2:

设置mybatis.configuration.local-cache-scope=statement后,即使 xmxxxxl 语句中配置useCache="true",一级缓存均失效。

总结:

•Mybatis一级缓存的生命周期和SqlSession一致。

•Mybatis的缓存是一个粗粒度的缓存,没有更新缓存和缓存过期的概念,同时只是使用了默认的hashmap,也没有做容量上的限定。

•Mybatis的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,有操作数据库写的话,会引起脏数据,建议是把一级缓存的默认级别设定为

Statement,即不使用一级缓存。

二、开启二级缓存,需要进行设置。

#一级缓存状态:关闭 #

mybatis.configuration.local-cache-scope=statement

#二级缓存状态:开启 #

mybatis.configuration.cache-enabled=true

mapper定义中添加标签

cache 用来声明使用二级缓存,可以自定义属性:

•type: cache使用的类型,默认是PerpetualCache,这在一级缓存中提到过。

•eviction: 定义回收的策略,常见的有FIFO,默认LRU

•flushInterval: 配置一定时间自动刷新缓存,单位是毫秒

•size: 最多缓存对象的个数

•readOnly: 是否只读,若配置可读写,则需要对应的实体类能够序列化。

•blocking: 若缓存中找不到对应的key,是否会一直blocking,直到有对应的数据进入缓存。

cache-ref代表引用别的命名空间配置,使用同一个 Cache。

测试:重启应用报错:

Caused by: java.io.NotSerializableException: com.sitech.acctmgr.pub.entity.VarDateEntity

没有序列化?将VarDateEntity序列化。

public class VarDateEntity implements Serializable {

重启应用,Postman第一次SqlSession 事务调用中,两次相同的查询:

两次均调用 sql查询了数据库。

原因:同一个 SqlSession 中,在执行完毕后进行提交commit()才会进入缓存。

Postman第二次事务执行,调用相同的 sql:

使用了缓存。命中率:Cache Hit Ratio : 0.3333333333333333,为何是0.3,因为总共查询了3次,本次使用了缓存。

再次查询,命中率就会变为0.5:

总结:

二级缓存不同于一级缓存,需要使接受数据的 POJO类序列化;

同一事务中的查询信息,在事务提交之后,才会把查询数据提交缓存。

返回的缓存数据是实际缓存实例,不是拷贝,所以存在被修改的情况!!!

频繁更新的操作不建议使用。手动修改数据库表中的查询数据会出现脏读!!!

二级缓存对细粒度的数据级别的缓存实现不好,不能够单独刷新某条数据!!!方案?EhcacheCache。

以上是在 SpringBoot 中,对Mybatis的缓存的查询类测试。

关于更新类的测试结果总结:

update操作是否会刷新该namespace下的二级缓存;

Mybatis的二级缓存不适应用于映射文件中存在多表查询的情况。如何解决?使用cache-ref 引入其他关联表所载 namespace。

单应用方案:

二级缓存?业务第一次的时候做的缓存。

单独做缓存?应用启动的时候静态加载配置。业务无感知。

分布式方案:

分布式缓存redis?

使用内存数据库?

mybatis源码分析可以查看下附帖子,在很多搜索结果里面,是比较全面的。

相关文档
最新文档