【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缓存。
-
MyBatis一级缓存的生命周期和SqlSession一致。每次执行update前都会清空localCache。
-
MyBatis一级缓存内部设计简单,只是一个没有容量限定的HashMap,在缓存的功能性上有所欠缺。
-
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一下应该就明白了。


- Mybatis在生产环境,是否应该开启缓存功能
- mybatis 开启二级缓存
- Mybatis开启本地二级缓存和使用redis开启二级缓存
- Mybatis 之 二级缓存
- 你尝试过在mybatis某个mapper上同时配置<cache/>和<cache-ref/>吗?
- 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 客户端。操作方法如下: …...
如何入侵服务器
根据中华人民共和国刑法: 第二百八十六条违反国家规定,对计算机信息系统功能进行删除、修改、增加、干扰,造成计算机信息系统不能正常运行,后果严重的,处五年以下有期徒刑或者拘役;后果特别严重的ÿ…...
在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…...
Python|GIF 解析与构建(5):手搓截屏和帧率控制
目录 Python|GIF 解析与构建(5):手搓截屏和帧率控制 一、引言 二、技术实现:手搓截屏模块 2.1 核心原理 2.2 代码解析:ScreenshotData类 2.2.1 截图函数:capture_screen 三、技术实现&…...
Linux 文件类型,目录与路径,文件与目录管理
文件类型 后面的字符表示文件类型标志 普通文件:-(纯文本文件,二进制文件,数据格式文件) 如文本文件、图片、程序文件等。 目录文件:d(directory) 用来存放其他文件或子目录。 设备…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
消息队列系统设计与实践全解析
文章目录 🚀 消息队列系统设计与实践全解析🔍 一、消息队列选型1.1 业务场景匹配矩阵1.2 吞吐量/延迟/可靠性权衡💡 权衡决策框架 1.3 运维复杂度评估🔧 运维成本降低策略 🏗️ 二、典型架构设计2.1 分布式事务最终一致…...
VisualXML全新升级 | 新增数据库编辑功能
VisualXML是一个功能强大的网络总线设计工具,专注于简化汽车电子系统中复杂的网络数据设计操作。它支持多种主流总线网络格式的数据编辑(如DBC、LDF、ARXML、HEX等),并能够基于Excel表格的方式生成和转换多种数据库文件。由此&…...
ui框架-文件列表展示
ui框架-文件列表展示 介绍 UI框架的文件列表展示组件,可以展示文件夹,支持列表展示和图标展示模式。组件提供了丰富的功能和可配置选项,适用于文件管理、文件上传等场景。 功能特性 支持列表模式和网格模式的切换展示支持文件和文件夹的层…...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...
