MyBatis一级缓存的笔记及记录
精髓内容来源于《图灵学院》
- 一、概述:
一级缓存是MyBatis天然自带的,是默认开启且没有关闭的地方,1级缓存只能作用于查询回话中,所以也叫会话缓存;
这里举个例子:
订单表存在一对多的关系,为了尽可能的减少join的查询,进行了分阶段查询; 先查询出订单表,在根据订单的用户ID查询用户信息表,最后将数据进行整合。如果订单表中存在重复的用户ID,就会出现很多没有必要的重复查询。 1级缓存解决了这个问题(1个语句被执行多次,也就是大家说的“N+1”的问题),在同一次查询回话中如果出现相同的语句及参数,就会从缓存中取出,不会直接从数据库端拉取数据。
- 二、使用条件及限制:
一级缓存又称为本地缓存,大致限制如下:
- 必须是相同的SQL和参数;
- 必须是同一个会话;
- 必须是相同的Mapper;
- 必须是相同的接口及方法;
- 查询前不能执行session.clearCache();
- 查询语句中间不能出现增删改的原子操作,因为“增删改”操作后会自动调用session.clearCache();这里需要注意,是否更新1级缓存是取决于你的注解或者XML原标签,也就是说如果@Update("select * from test where id=#{id}")也会清空1级缓存;
- 三、实现原理:
实现了Cache接口——PerpetualCache类,cache变量就是一个简单的HashMap,所以一级缓存就是通过HashMap实现的;
这里需要特别注意一下:
因为是基于HashMap实现,在查询时另一个会话并发去修改查询的数据的时候,一级缓存会有效,也就是非线程安全,存在并发问题,但是一级缓存又是属于本地缓存而且基于当前会话,所以这个并发问题可以忽略,您难道在自己的代码里还要实现内部并发吗?:);
- 四、缓存调用逻辑:
- 调用mapper的执行方法(这里的mapper对象是通过Java代理实现的);
- DefaultSqlSession.selectList方法开始进行处理,所有查询都会进入这里;
- CachingExecutor.query:缓存执行器开始执行获取数据处理;
- BaseExecutor.query:查询缓存信息。这里注意一下,clearLocalCache方法是清空缓存调用的方法,(如果当前没有关闭,就执行清空操作,这里清空是全部清空);
- PerpetualCache.getObject:获取缓存;
后续可能持续更新
MyBatis一级缓存的笔记及记录的更多相关文章
- MyBatis二级缓存的笔记及记录
一.什么是二级缓存: 由于一级缓存是一次性的.临时的:每个会话都会创建一个新的:多个会话之间是不能共享的: 二级缓存用于解决一级缓存的不足:每一个“namespace”都会对应一个二级缓存:执行查询的 ...
- 0065 MyBatis一级缓存与二级缓存
数据库中数据虽多,但访问频率却不同,有的数据1s内就会有多次访问,而有些数据几天都没人查询,这时候就可以将访问频率高的数据放到缓存中,就不用去数据库里取了,提高了效率还节约了数据库资源 MyBatis ...
- Mybatis一级缓存和二级缓存 Redis缓存
一级缓存 Mybatis的一级缓存存放在SqlSession的生命周期,在同一个SqlSession中查询时,Mybatis会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个Map对 ...
- Mybatis一级缓存的锅
问题背景 项目开发中有一个树形数据结构,不像经典组织结构树.菜单级别树,我们这个树形结构是用户后期手动建立起来的关系.因此数据库表结构为两张表:数据记录表.记录关系表,通过业务规则限制,形成的树形结构 ...
- MyBatis 一级缓存与二级缓存
MyBatis一级缓存 MyBatis一级缓存默认开启,一级缓存为Session级别的缓存,在执行以下操作时一级缓存会清空 1.执行session.clearCache(); 2.执行CUD操作 3. ...
- MyBatis一级缓存引起的无穷递归
MyBatis一级缓存引起的无穷递归 引言: 最近在项目中参与了一个领取优惠劵的活动,当多个用户领取同一张优惠劵的时候,使用了数据库锁控制并发,起初的设想是:如果多个人同时领一张劵,第一个到达的人领取 ...
- mybatis一级缓存详解
mybatis缓存分为一级缓存,二级缓存和自定义缓存.本文重点讲解一级缓存 一:前言 在介绍缓存之前,先了解下mybatis的几个核心概念: * SqlSession:代表和数据库的一次会话,向用户提 ...
- MyBatis 一级缓存避坑
MyBatis 一级缓存(MyBaits 称其为 Local Cache)无法关闭,但是有两种级别可选: package org.apache.ibatis.session; /** * @autho ...
- 关于mybatis 一级缓存引发的问题
场景: 由于在一个方法中存在多个不同业务操作 private void insertOrUpdateField(CompanyReport entity) { //计算并数据 calcReportDa ...
随机推荐
- List集合的方法总结
1. 添加方法 boolean add(E e): 向集合的末尾添加指定的元素 boolean addAll(Collection<? extends E> c): 向集合的末尾添加一个指 ...
- Angular CLI 创建你的第一个 Angular 示例程序
第一步:安装 Angular CLI 你要使用 Angular CLI 来创建项目.创建应用和库代码,并执行多种开发任务,比如测试.打包和发布. 全局安装 Angular CLI. 要想使用 npm ...
- R_Studio(关联)对dvdtrans.csv数据进行关联规则分析
dvdtrans.csv数据:该原始数据仅仅包含了两个字段(ID, Item) 用户ID,商品名称(共30条) #导入arules包 #install.packages("arules&qu ...
- echarts之bootstrap选项卡不能显示其他标签echarts图表
在echarts跟bootstrap选项卡整合的时候,默认第一个选中选项卡可以正常加载echarts图表,但是切换其他选项的时候不能渲染出其他选项卡echarts图表. 解决方法: 在js中添加代码: ...
- Excel导入导出工具(简单、好用且轻量级的海量Excel文件导入导出解决方案.)
Excel导入导出工具(简单.好用且轻量级的海量Excel文件导入导出解决方案.) 置顶 2019-09-07 16:47:10 $9420 阅读数 261更多 分类专栏: java 版权声明:本 ...
- C++入门经典-例6.20-修改string字符串的单个字符
1:使用+可以将两个string 字符串连接起来.同时,string还支持标准输入输出函数.代码如下: // 6.20.cpp : 定义控制台应用程序的入口点. // #include "s ...
- Dijk入门(杭电2544题)
#include<iostream> #include<cstring> using namespace std; #define INF 0x3f3f3f3f int n,m ...
- shell脚本获取绝对路径
当前脚本全路径 echo $(readlink -f "$0") 获取绝对路径(不带文件名) echo $(dirname $(readlink -f "$0" ...
- Uep的静态下拉和动态下拉建立
uep的静态下拉和动态下拉的建立极其省事,下面介绍静态下拉的建立 静态下拉 第一步:点击增加,输入信息 第二步: 第三步:保存 第四部: 静态下拉就建立完毕了 下面介绍动态下啦建立,动态下拉更简单 动 ...
- SAEJ1757-1-2015(一)
SURFACE VEHICLE STANDARD 表面车辆标准 Standard Metrology for Vehicular Displays 车载显示 ...