首页 > 其他分享 >mybatis 一级、二级缓存机制

mybatis 一级、二级缓存机制

时间:2023-01-12 17:22:58浏览次数:57  
标签:缓存 一级 Cache SqlSession MyBatis 二级缓存 mybatis

 MyBatis 提供了对缓存的支持,分为一级缓存和二级缓存

 

 

一级缓存是 SqlSession 级别的缓存。在操作数据库时需要构造 SqlSession 对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的是 SqlSession 之间的缓存数据区(HashMap)是互相不影响。

二级缓存是 Mapper 级别的缓存,多个 SqlSession 去操作同一个 Mapper 的 sql 语句,多个 SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。

一级缓存

具体执行过程如下图所示:

 

 

 

SqlSession 是一个接口,提供了一些 CRUD 的方法,而 SqlSession 的默认实现类是 DefaultSqlSession,DefaultSqlSession 类持有 Executor 接口对象,而 Executor 的默认实现是 BaseExecutor 对象,每个 BaseExecutor 对象都有一个 PerpetualCache 缓存,也就是上图的  Local Cache。

当用户发起查询时,MyBatis 根据当前执行的语句生成 MappedStatement,在 Local Cache 进行查询,如果缓存命中的话,直接返回结果给用户,如果缓存没有命中的话,查询数据库,结果写入 Local Cache,最后返回结果给用户。

 

 

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

  • MyBatis 一级缓存内部设计简单,只是一个没有容量限定的 HashMap,在缓存的功能性上有所欠缺。

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

  • 只有在开启了数据库事物【@EnableTransactionManagement】并且处于一个被事物标注的方法下【直接或间接】才会生效。

二级缓存

 

 

 二级缓存开启后,同一个 namespace 下的所有操作语句,都影响着同一个 Cache,即二级缓存被多个 SqlSession 共享,是一个全局的变量。

当开启缓存后,数据的查询执行的流程就是 二级缓存 -> 一级缓存 -> 数据库。

MyBatis 是默认关闭二级缓存的,因为对于增删改操作频繁的话,那么二级缓存形同虚设,每次都会被清空缓存。

 

  • MyBatis 的二级缓存相对于一级缓存来说,实现了 SqlSession 之间缓存数据的共享,同时粒度更加的细,能够到 namespace 级别,通过 Cache 接口实现类不同的组合,对 Cache 的可控性也更强。

  • MyBatis 在多表查询时,极大可能会出现脏数据(多表查询语句所在的 namspace 无法感应到其他 namespace 中的语句对多表查询中涉及的表进行的修改),有设计上的缺陷,安全使用二级缓存的条件比较苛刻。

  • 在分布式环境下,由于默认的 MyBatis Cache 实现都是基于本地的,分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将 MyBatis 的 Cache 接口实现,有一定的开发成本,直接使用 Redis、Memcached 等分布式缓存可能成本更低,安全性也更高。

关闭一二级缓存

建议禁用一级与二级缓存,分布式应用程序应该是必须要禁用的,单体应用如果没有禁用一级缓存,则要建议多线程共享同一个SqlSession。

方法一:禁用一级缓存:mybatis没有提供一级缓存的启用、禁用开关,但在Mapper文件对应的语句中增加flushCache="true"可以达到实际禁用一级缓存的效果,一般同时还会加上useCache="false",以便关闭二级缓存;

方法二:将mybatis一级缓存级别设置为statement可以事实上达到禁用一级缓存的效果;
mybatis:
  configuration:
    local-cache-scope: session  //statement 一级缓存
    cache-enabled: false  //这里是二级缓存

 

参考文章

 

标签:缓存,一级,Cache,SqlSession,MyBatis,二级缓存,mybatis
From: https://www.cnblogs.com/wyhb008/p/17033065.html

相关文章

  • SpringBoot+Mybatis-plus整合easyExcel批量导入Excel到数据库+导出Excel
    SpringBoot+Mybatis-plus整合easyExcel批量导入Excel到数据库+导出Excel 一、前言今天小编带大家一起整合一下easyExcel,之所以用这个,是因为easyExcel性能比较好,不会......
  • MyBatisPlus
    MyBatisPlus导入坐标SpringBoot并没有收录mybatisplus,所以需要自己导入坐标<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus......
  • 01-mybatis解析XML文件
    <?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEconfigurationPUBLIC"-//mybatis.org//DTDConfig3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd"><c......
  • mybatis踩坑之integer类型是0的时候会被认为0!=''是假
    当你的参数类型是integer类型,并且传的是0的时候,在SQL里面做if判断的时候<iftest="auditStatus!=nullandauditStatus!=''">ANDaudit_status=#{aud......
  • 数据源、JDBC、MyBatis、连接池(Druid)
    概念数据源(DataSource)是一种数据库对编程提供的一个接口,每个数据源对应一个数据库。一个例子就是在使用IDEA的数据库插件时,通常需要选择数据源,此处的数据源就是指这个......
  • 学习笔记——MyBatis自动映射与自定义映射;Mybatis延迟加载
    2023-01-10 一、MyBatis自动映射与自定义映射1、自动映射:在映射文件中使用的是“resultType”。指的是自动将数据库中表的字段与类中的属性进行关联映射。2、自定义映......
  • SpringBoot+Mybatis-plus整合easyExcel批量导入Excel到数据库+导出Excel
    一、前言今天小编带大家一起整合一下easyExcel,之所以用这个,是因为easyExcel性能比较好,不会报OOM!市面上常见的导入导出Excel分为三种:hutooleasyExcelpoihutool和eas......
  • Mybatis——实现批量更新
    一、概述mybatis中实现批量插入是很简单的,相比大家都知道,这里就不赘述,本文主要讲述如何实现批量更新。 下面介绍本文要讲的几种方式主要是在xml中实现,不包含需要改动代......
  • Mybatis
    缓存与Executor一级缓存一级缓存是sqlSession级别的,默认开启,在BaseExecutor中实现,其具体实现为key-value结构的HashMap。一级缓存命中条件1、查询sql和参数值必须相同;......
  • 初学mybatis
    MybatisIDEA创建一个空项目,然后添加Maven模块maven项目路径如下所示--项目名 --/src --/main#存放主程序java代码和资源 --/java #java代码 --/resources#配......