【理论驱动应用】该不该使用Mybatis一级缓存和二级缓存?

学习MyBatis一级缓存概念、使用、存在问题及解决方法从而确定该不该用Mybatis一级缓存和二级缓存。

一级缓存

概念

  • 一次数据库会话中,执行多次查询条件完全相同的SQL,MyBatis通过一级缓存的方案优化这部分场景。
  • SqlSession级别的缓存。

使用

Mybatis配置文件中配置缓存设置,开启一级缓存

  • cacheEnabled=true
  • localCacheScope=SESSION

原理

  • 在一个SqlSession中,查询相同条件的查询,会查缓存
  • 缓存失效:同一个session中对相同的记录进行修改操作时,该记录的缓存会失效
  • 只在SqlSession内部共享
  • 一个没有容量限定的HashMap

存在问题

  • 默认的SESSION的缓存,对于不同SqlSession中,可能读到脏数据。
  • 分布式环境下失效

如何解决存在问题

  • 非分布式部署环境下,设置localCacheScope为STATEMENT
  • 未提供自定义实现,无法缓存到redis等缓存中

二级缓存

概念

  • namespace缓存
  • 相同namespace下所有操作语句,都影响着同一个Cache
  • 多个SqlSession共享

特点

  • 实现了SqlSession之间的数据共享
  • 粒度更细,能够到namespace级别

使用

Mybatis配置文件中配置缓存设置,开启而级缓存

  • cacheEnabled=true

在mapper文件中添加cache相关标签

cache
属性
  • type:cache使用类型,默认值:PerpetualCache,可以自定义实现
  • eviction:回收策略,取值LRU、FIFO、SOFT、WEAK,默认值为:LRU
  • size:最多缓存对象的个数
  • readOnly:是否只读,若配置可读写,则需要对应的实体类能够序列化。
  • blocking:若缓存中找不到对应的key,是否会一直blocking,直到有对应的数据进入缓存。
cache-ref

代表引用别的命名空间的Cache配置,两个命名空间的操作使用的是同一个Cache。

属性

namespace

存在问题

  • 多表查询时,对于不同namespace,维护的缓存可能不一致,会出现脏读
  • 基于本地的,分布式环境无效

如何解决存在问题

  • 多表查询时脏读的解决方法:多表放在同一个namespace下
  • 分布式环境解决方法:使用redis实现自定义的缓存类型

一级缓存、二级缓存执行流程

优先查询二级缓存,其次查询一级缓存,最后查询数据库

用不用Mybatis缓存

一级缓存和二级缓存都存在相关问题,如果能够解决相关问题的话可以使用,只是需要人为去改造,不通用

参考

  • Mybatis XML 配置
  • Mybatis XML 映射器
  • 聊聊MyBatis缓存机制

你可能感兴趣的:(mybatis,分布式,数据库)