当前位置: 首页 > news >正文

【Mybatis源码解析】一级缓存和二级缓存源码解析

文章目录

    • 缓存使用
    • 缓存源码
    • 测试代码

上一篇《【Mybatis源码解析】mapper实例化及执行流程源码分析》,主要讲解了Mybatis的基本原理一级执行的流程,这一章来讲一下Mybatis的两个缓存:一级缓存和二级缓存。

因为网上大部分都是使用xml配置的方式来使用缓存,所以我们这里讲解一下注解的方式。

一级缓存
一级缓存是SqlSession级别。一级缓存的作用域是 SqlSession , Mabits 默认开启一级缓存。 在同一个SqlSession中,执行相同的SQL查询时;第一次会去查询数据库,并写在缓存中,第二次会直接从缓存中取。 当执行SQL时候两次查询中间发生了增删改的操作,则SqlSession的缓存会被清空。

一级缓存 Mybatis的内部使用一个HashMap,key为hashcode+statementId+sql语句。Value为查询出来的结果集映射成的java对象。 Sqlsession执行insert、update、delete等操作commit后会清空该SqlSession缓存。

  1. MyBatis一级缓存的生命周期和SqlSession一致。每次执行update前都会清空localCache。

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

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

二级缓存
二级缓存是Mapper级别的缓存,多个SqlSession去操作同一个Mapper中的sql语句,则这些SqlSession可以共享二级缓存,即二级缓存是跨SqlSession的。简单说就是同一个namespace 下的 mapper 映射文件中,用相同的sql去查询数据,会去对应的二级缓存内取结果。

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

MyBatis在多表查询时,极大可能会出现脏数据,有设计上的缺陷,安全使用二级缓存的条件比较苛刻。

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

总结: 生产上建议关闭一级和二级缓存。

缓存使用

yml配置:

mybatis:configuration:# 驼峰大小写经典 Java 属性名 aColumn 的自动映射,默认值为falsemap-underscore-to-camel-case: true# statement: 关闭一级缓存;session:开启一级缓存 默认为sessionlocal-cache-scope: session# 开启二级缓存 默认为truecache-enabled: true# 打印sqllog-impl: org.apache.ibatis.logging.stdout.StdOutImpl

mapper接口(注解版):

@CacheNamespace注解:
作用于mapper接口上面,是用来实现二级缓存的,如果不指定实现类的话,默认就是PerpetualCache(实际上就是hashmap实现的)

@CacheNamespaceRef注解:
在多个命名空间中共享相同的缓存配置和实例

@Options(useCache = true,flushCache = Options.FlushCachePolicy.DEFAULT)注解:
useCache :是否用缓存,默认为true。
flushCache :是否刷新缓存,默认不刷新。

mapper接口(xml版):略。

在这里插入图片描述

缓存源码

新版的源码并没有太多改变,发送请求时,先从二级缓存中取,未取到则去一级缓存中取,仍未取到会去数据库中查,再存到一级缓存中,当事务提交之后,会存到二级缓存中,值得注意的是,mybatis中的一些cashe相关类挺有意思的,用来解决不同场景的问题,比如脏读。因为源码比较简单易懂,确实没什么值得可以写的,我想大家cv一下我的demo,debug一下应该就明白了。

在这里插入图片描述
在这里插入图片描述

  1. Mybatis在生产环境,是否应该开启缓存功能
  2. mybatis 开启二级缓存
  3. Mybatis开启本地二级缓存和使用redis开启二级缓存
  4. Mybatis 之 二级缓存
  5. 你尝试过在mybatis某个mapper上同时配置<cache/>和<cache-ref/>吗?
  6. Mybatis缓存源码分析

测试代码

controller

package com.ossa.web3.controller;import com.ossa.web3.bean.User;
import com.ossa.web3.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/user")
public class TestController {@Autowiredprivate UserMapper userMapper;@GetMapping("/l1cache")@Transactionalpublic User l1cache() {User user1 = userMapper.selectById("c5329f3b-3e98-4722-8faf-e87d9b981871");User user2 = userMapper.selectById("c5329f3b-3e98-4722-8faf-e87d9b981871");return null;}@GetMapping("/l2cache")public User l2cache() {return userMapper.selectById("c5329f3b-3e98-4722-8faf-e87d9b981871");}@DeleteMapping("/deleteById")public User deleteById() {return userMapper.deleteById("c5329f3b-3e98-4722-8faf-e87d9b981871");}
}

实体类

package com.ossa.web3.bean;import lombok.Data;import java.io.Serializable;@Data
public class User implements Serializable {private String id;private String name;private Integer age;
}

mapper接口

package com.ossa.web3.mapper;import com.ossa.web3.bean.User;
import org.apache.ibatis.annotations.*;@CacheNamespace
public interface UserMapper {@Select(value = "select * from user where id = #{id}")@Options(useCache = true,flushCache = Options.FlushCachePolicy.DEFAULT)User selectById(String id);@Delete(value = "delete from user where id = #{id}")@Options(useCache = false,flushCache = Options.FlushCachePolicy.TRUE)User deleteById(String id);
}

application.yml

spring:datasource:driver-class-name: com.mysql.jdbc.Driverurl: jdbc:mysql://issavior-aliyun-rds.mysql.rds.aliyuncs.com:3306/test?useUnicode=true&charsetEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=trueusername: rootpassword: rootmybatis:configuration:# 驼峰大小写经典 Java 属性名 aColumn 的自动映射,默认值为falsemap-underscore-to-camel-case: true# statement: 关闭一级缓存;session:开启一级缓存local-cache-scope: session# 开启二级缓存cache-enabled: true# 打印sqllog-impl: org.apache.ibatis.logging.stdout.StdOutImpl############### Sa-Token 配置 (文档: https://sa-token.cc) ##############
#sa-token:
#  # token名称 (同时也是cookie名称)
#  token-name: satoken
#  # token有效期,单位s 默认30, -1代表永不过期
#  timeout: 2592000
#  # token临时有效期 (指定时间内无操作就视为token过期) 单位: 秒
#  activity-timeout: -1
#  # 是否允许同一账号并发登录 (true时允许一起登录,false时新登录挤掉旧登录)
#  is-concurrent: true
#  # 在多人登录同一账号时,是否共用一个token (true时所有登录共用一个token,false时每次登录新建一个token)
#  is-share: true
#  # token风格
#  token-style: uuid
#  # 是否输出操作日志
#  is-log: false

相关文章:

【Mybatis源码解析】一级缓存和二级缓存源码解析

文章目录缓存使用缓存源码测试代码上一篇《【Mybatis源码解析】mapper实例化及执行流程源码分析》,主要讲解了Mybatis的基本原理一级执行的流程,这一章来讲一下Mybatis的两个缓存:一级缓存和二级缓存。 因为网上大部分都是使用xml配置的方式…...

你知道MES实施的要点吗?

随着国家行动纲领:中国制造2025(智能制造)的发布,MES系统在制造业的工厂中所占比重越来越大,越来越多的工厂选择使用MES完成工厂的信息化、数字化、智能化生产。伴随着企业对MES的需求不断增大,生产MES的厂…...

告诉你为什么为什么 SELECT COUNT(*) FROM table 在 InnoDB 引擎中比 MyISAM引擎中的速度慢

统计一张表的总数量,是我们开发中常有的业务需求,通常情况下,我们都是使用 select count(*) from table SQL 语句来完成。随着业务数据的增加,你会发现这条语句执行的速度越来越慢,为什么它会变慢呢? 为什…...

Redis 命令和Redis key键

Redis 命令 Redis 命令用于在 Redis 服务器上执行一些操作,而命令运行的方式是通过客户端命令行来执行的,这种方式也被称为“命令行模式”。因此想要在 Redis 服务器上运行命令,您首先需要开启一个 Redis 客户端。操作方法如下: …...

如何入侵服务器

根据中华人民共和国刑法: 第二百八十六条违反国家规定,对计算机信息系统功能进行删除、修改、增加、干扰,造成计算机信息系统不能正常运行,后果严重的,处五年以下有期徒刑或者拘役;后果特别严重的&#xff…...

在Windows10上安装虚拟机---VMware 17 Pro下载与安装

在Windows10上安装虚拟机---VMware下载与安装0 前言1 下载VMware 17 pro2 安装VMware 17 Pro3. 打开Vmware0 前言 电脑原生系统:Windows10虚拟机软件:VMware 17 pro准备好安装虚拟机的文件夹路径 1 下载VMware 17 pro 下载网址:VMware 官网…...

生命周期函数、组件

1. 生命周期函数 beforeCreate : 无法通过 vm 访问data 中的数据、methods 中的方法created :可以访问 vm 中的 data 的数据, methods 中的方法beforeMount:为经 Vue 编译的 dommounted:经过 vue 编译的 dom &#x…...

蓝桥杯 stm32 PWM 测量频率

本文代码使用 HAL 库。 文章目录 前言一、PWM 原理图:二、CubeMX 创建工程:三、PWM 单路测频:四、详细代码:1. 获取 CNT函数。2. 设置CNT为 0 函数3. 开启TIM2_CH1的输入捕获中断函数4. TIM 回调函数5. 在 LCD 上显示 R40 和 R39 的频率。总结前言 一、PWM 原理图: 参考…...

Docker CPU 资源控制

01-本章背景知识 在生产环境里运行服务的一个主要问题是如何公平有效的进行资源分配。 1、Docker 容器使用核心操作系统的 Cgroups 管理容器的 CPU资源分配。 2、Docker 容器资源竞争时,默认使用简单均分(CFS)算法。 3、Docker 容器也可以根…...

小红书数据平台:笔记爆文率提升的三大秘诀公式!

导语 对于小红书商家 / 博主来说,写出爆文就像买彩票,根本不能预知哪一篇会爆。2023年,小红书哪些内容会脱颖而出呢?我们又该如何把握热点趋势,实现优质内容转化出爆文~ 美妆作为小红书的长红赛道,本文我…...

Spring MVC 之Tomcat启动流程

从web.xml说起在开始 Spring MVC 的分析之前,先来聊一聊 Java 初学者接触的最多的 Java Web 基础。还记得我的第一个 Web 工程是由 Servlet、Velocity 和 Filter 来完成的,那时几乎所有人都是根据 Servlet、JSP 和 Filter 来编写自己的第一个 Hello Worl…...

大疆车载更新产品矩阵,覆盖从主动安全到城区领航的全场景

新年智驾供应商的攻势,也像车企一样猛烈。大疆车载近期趁着官网更新,对外公布了梳理后的智驾方案序列,覆盖8大功能产品:主动安全、行车辅助、泊车辅助、记忆泊车、记忆行车、跨层记忆泊车、领航高速、领航城区。需要关注的是&…...

总结Anisble中的任务执行控制并练习

文章目录一、循环1.简单循环2.循环散列或字典列表二、条件三、触发器四、处理失败任务1.ignore_errors2.force_handlers3.changed_when4.failed_when5.block五、 练习建立大小为1500M名为/dev/sdb1的设备利用ansible循环安装且开启vsftpd,apache,dns&…...

PMP好考吗,有多大的价值?

关于PMP考试题型及考试内容,PMP考试共200道单选题,其中25道题不计分,会被随机抽查,答对106道题以上通过考试,参考比例106/175,60.57%估计答对(10625)道题及上即可通过,参…...

http常用状态码(204,304, 404, 504,502)含义

网络状态码含义,常用(204,304, 404, 504,502) 200 – 服务器成功返回网页 404 – 请求的网页不存在 503 – 服务不可用 常见HTTP状态码大全 1xx(临时响应) 表示临时响应并需要请求者继…...

记录锁,间隙锁,插入意向锁,临键锁兼容关系

插入意向锁是什么? 注意!插入意向锁名字里虽然有意向锁这三个字,但是它并不是意向锁,它属于行级锁,是一种特殊的间隙锁。 在MySQL的官方文档中有以下重要描述: An Insert intention lock is a type of gap…...

map相关接口(map接口、HashMap、LinkedHashMap、TreeMap)

Java知识点总结:想看的可以从这里进入 目录8.3、map结构8.3.1、 map接口8.3.2、HashMap8.3.3、LinkedHashMap8.3.4、TreeMap8.3、map结构 8.3.1、 map接口 map的集合是以键值对的形式存在的 (key-value),每个键只能对应一个值,通常通过键去…...

抽象工厂模式(Abstract Factory Pattern)

1.抽象工厂模式定义: 抽象工厂模式提供了一个创建一系列相关或者相互依赖对象的接口,无需指定它们具体的类 2.抽象工厂模式适用场景: 客户端(应用层)不依赖于产品类实例如何被创建、实现等细节强调一系列相关的产品对象(属于同一产品族)一起使用创建对象需要大量…...

Linux驱动学习笔记

驱动学习笔记 1、字符设备驱动 Linux 驱动有两种运行方式 第一种就是将驱动编译进 Linux 内核中,这样当 Linux 内核启 动的时候就会自动运行驱动程序。 第二种就是将驱动编译成模块(Linux 下模块扩展名为.ko),在 Linux 内核启动以后使用“insmod”命…...

tarfile — 访问 Tar 压缩文件

tarfile — 访问 Tar 压缩文件 1.概述 tarfile 模块提供对 Unix tar 存档的读写访问,包括压缩文件。除了 POSIX 标准之外,还支持几种 GNU tar 扩展。还提供处理 Unix 特殊文件类型,如硬链接和软链接,以及设备节点. 虽然 tarfile…...

别再死记硬背栈顶指针了!用C语言手把手实现顺序栈(附完整可运行代码)

从零构建C语言顺序栈:破解栈顶指针的终极迷思 初学数据结构时,栈顶指针的初始值设定总是让人困惑——为什么有的教材用top -1,有的却用top 0?这看似简单的数字差异,背后却隐藏着对栈本质理解的深刻分歧。本文将用300…...

IsaacGym力传感器实战:从初始化到数据读取的保姆级避坑指南

IsaacGym力传感器实战:从初始化到数据读取的保姆级避坑指南 在机器人仿真开发中,力传感器的数据采集往往是实现物理交互的关键环节。作为NVIDIA推出的高性能机器人仿真平台,IsaacGym凭借其GPU加速能力为开发者提供了强大的工具链,…...

网络架构革新:SDN基本原理深度解析与核心优势(超详细图解)

网络架构革新:SDN基本原理深度解析与核心优势(超详细图解)前言一、SDN:基本概念1.1 官方定义1.2 通俗理解1.3 SDN核心设计原则二、SDN:标准三层体系架构(必掌握)三、SDN:基本工作原理…...

从半桥到全桥:无刷直流电机驱动电路的设计演进与选型指南

1. 无刷直流电机驱动电路的基础认知 第一次接触无刷直流电机驱动设计时,我被各种拓扑结构绕得头晕。直到亲手烧毁几个MOS管后,才真正理解半桥和全桥的本质区别。简单来说,驱动电路就像交通指挥系统,决定电流如何流经电机绕组。半桥…...

FreeRTOS进阶指南:流缓冲区与消息缓冲区的实战应用与性能优化

1. 流缓冲区与消息缓冲区基础解析 第一次接触FreeRTOS的缓冲区功能时,我完全被官方文档绕晕了。直到在真实项目中踩了几个坑才明白,这俩兄弟其实就像快递站的两种取件方式:流缓冲区是自助取件(按重量取),消…...

[tomcat最新漏洞20260218] CVE-2026-24734 Apache Tomcat and Tomcat Native - OCSP revocation bypass

文章目录 I 主机漏洞 漏洞描述 漏洞修复建议: Upgrade to Apache Tomcat 9.0.115 or later II 漏洞处理 下载最新版本tomcat 9.0.117 安装最新tomcat III 为了同一个tomcat版本安装多个服务 安装服务 验证服务是否启动成功 迁移配置信息 Tomcat7迁移到Tomcat9 需要删除JasperL…...

Agent Client Protocol 全景解析斗

1. 核心概念 在 Antigravity 中,技能系统分为两层: Skills (全局库):实际的代码、脚本和指南,存储在系统级目录(如 ~/.gemini/antigravity/skills)。它们是“能力”的本体。 Workflows (项目级)&#xff1a…...

MedGemma Medical Vision Lab镜像免配置:Docker一键运行+Web界面自动加载MedGemma权重

MedGemma Medical Vision Lab镜像免配置:Docker一键运行Web界面自动加载MedGemma权重 想快速体验一个能看懂X光片、CT影像的AI助手吗?今天介绍的MedGemma Medical Vision Lab,让你无需任何复杂的模型下载和配置,就能在本地运行一…...

手把手教你为高通骁龙平台添加新传感器:从供应商驱动到系统集成的完整流程

高通骁龙平台传感器集成实战:从驱动适配到系统验证的全链路解析 当一款新型传感器需要集成到高通骁龙平台时,工程师面临的不仅是代码修改的挑战,更是一个涉及硬件抽象层、通信协议、电源管理和系统架构的复杂工程。以SC7A20加速度传感器为例&…...

用刚性小球定义的宇宙图景-超流体宇宙概述

一、 终极定义:相位场 ϕ 的唯一使命在这个超流体宇宙里,唯一真实的物理量是 “位置” 和 “时间”。但因为介质是连续的,我们无法用 “质点” 来描述整个场的演化。所以,为了数学上描述 “连续介质的运动”,我们必须引…...