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 ...
随机推荐
- SpringBoot2.0集成Shiro
1.shiro的三个核心概念: 1)Subject:代表当前正在执行操作的用户,但Subject代表的可以是人,也可以是任何第三方系统帐号.当然每个subject实例都会被绑定到SercurityMa ...
- maven项目创建2
添加依赖索引 但是默认是没有索引的,要手动创建索引 依赖范围 debug 配置 运行常见问题 处理办法,JDK重新安装 网络添加依赖网站
- the nearest point/vertex point of linestring
引用https://github.com/Toblerity/Shapely/issues/190 snorfalorpagus commented on 18 Oct 2014 The point ...
- MessagePack Java 0.6.X 快速开始指南 - 安装
0.6.x 版本的 MessagePack 已经过期被淘汰了.如果你现在开始使用 MessagePack 话,请不要使用这个版本. 我们再这里保留 0.6.x 版本的内容主要用于参考用途. 最新的 M ...
- Tomcat报错,内存溢出的错误Exception in thread "http-bio-8080-exec-13" java.lang.OutOfMemoryError: PermGen space
说是tomcat 内存溢出,然后按照网上看的搞一搞之后没出息这个问题了 原因是tomcat内存溢出,按照一到五步奏,在第三步加上那段参数.
- 十四周学习总结&简易记事本
学习总结: 一.JDBC: 1.JDBC提供里一套与平台无关的标准数据库操作接口和类,只要支持java的数据库厂商,所提供的数据库都可以以使用JDBC操作. 2.JDBC的主要操作类及接口: 3.JD ...
- leetcode-easy-string-28 Implement strStr()
mycode 77.15% class Solution(object): def strStr(self, haystack, needle): """ :type ...
- MethodChannel 实现flutter 与 原生通信
Flutter 步骤 目的:在flutter页面中主动调用原生页面中的方法. 1 在widget中,定义MethodChannel变量 static const MethodChannel metho ...
- 自定义Chrome的console(样式、打印图片、开关)
1.常用console类型 console.log() 常规打印 console.warn() 打印警告信息 console.error() 打印错误信息 console.time() 和 conso ...
- [VBA]指定列求和
##指定列求和 需求: 求和:列为“销售金额”的数值 Sub 求和()Dim i As Integer, j As IntegerFor i = 3 To 56For j = 15 To 81 Ste ...