Java教程

【Mybatis】Mybatis缓存(转载)

本文主要是介绍【Mybatis】Mybatis缓存(转载),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

转载:

  1. https://tech.meituan.com/2018/01/19/mybatis-cache.html

  2. https://www.cnblogs.com/zhengxl5566/p/11868656.html

1、概念介绍

  • 什么是一级缓存
    在日常开发过程中,经常会有相同的sql执行多次查询的情况,mybatis提供了一级缓存来优化这些查询,避免多次请求数据库。
    一级缓存在mybatis中默认是开启的并且是session级别,它的作用域为一次sqlSession会话。
  • 什么是二级缓存
    相对于一级缓存,二级缓存的作用域更广泛,它不止局限于一个sqlSession,可以在多个sqlSession之间共享,事实上,它的作用域是namespace。
    mybatis的二级缓存默认也是开启的,但由于他的作用域是namespace,所以还需要在mapper.xml中开启才能生效
  • 缓存的优先级
    通过mybatis发起的查询,作用顺序为:二级缓存->一级缓存->数据库 ,其中任何一个环节查到不为空的数据,都将直接返回结果
  • 缓存失效
    当在一个缓存作用域中发生了update、insert、delete 动作后,将会触发缓存失效,下一次查询将命中数据库,从而保证不会查到脏数据

2、一级缓存

一级缓存默认开启。但是有两点需求注意:

  1. 为什么开启事务
    由于使用了数据库连接池,默认每次查询完之后自动commite,这就导致两次查询使用的不是同一个sqlSessioin,根据一级缓存的原理,它将永远不会生效。
    当我们开启了事务,两次查询都在同一个sqlSession中,从而让第二次查询命中了一级缓存。读者可以自行关闭事务验证此结论。
  2. 两种一级缓存模式
    一级缓存的作用域有两种:session(默认)和statment,可通过设置local-cache-scope 的值来切换,默认为session。
    二者的区别在于session会将缓存作用于同一个sqlSesson,而statment仅针对一次查询,所以,local-cache-scope: statment可以理解为关闭一级缓存。

3、二级缓存

要正确的使用二级缓存,需完成如下配置的。

  1. 在MyBatis的配置文件中开启二级缓存。
<setting name="cacheEnabled" value="true"/>
  1. 在MyBatis的映射XML中配置cache或者 cache-ref 。

cache标签用于声明这个namespace使用二级缓存,并且可以自定义配置。

<cache/>   
  • type:cache使用的类型,默认是PerpetualCache,这在一级缓存中提到过。
  • eviction: 定义回收的策略,常见的有FIFO,LRU。
  • flushInterval: 配置一定时间自动刷新缓存,单位是毫秒。
  • size: 最多缓存对象的个数。
  • readOnly: 是否只读,若配置可读写,则需要对应的实体类能够序列化。
  • blocking: 若缓存中找不到对应的key,是否会一直blocking,直到有对应的数据进入缓存。

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

<cache-ref namespace="mapper.StudentMapper"/>

总结

  1. MyBatis的二级缓存相对于一级缓存来说,实现了SqlSession之间缓存数据的共享,同时粒度更加的细,能够到namespace级别,通过Cache接口实现类不同的组合,对Cache的可控性也更强。
  2. MyBatis在多表查询时,极大可能会出现脏数据,有设计上的缺陷,安全使用二级缓存的条件比较苛刻。
  3. 在分布式环境下,由于默认的MyBatis Cache实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将MyBatis的Cache接口实现,有一定的开发成本,直接使用Redis、Memcached等分布式缓存可能成本更低,安全性也更高。
这篇关于【Mybatis】Mybatis缓存(转载)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!