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

Mybatis的一级缓存与二级缓存

1. 缓存的概念

  1. 缓存的概念

    1. 在内存中临时存储数据,速度快,可以减少数据库的访问次数。
    2. 经常需要查询,不经常修改的数据,不是特别重要的数据都适合于存储到缓存中。

 

2. MyBatis的一级缓存

  1. MyBatis的一级缓存也是SqlSession的缓存。

  2. SqlSession对象中维护了一个Map集合,用于存储相互的缓存数据。

  3. 查询的时候,先从SqlSession的缓存中查找,如果有,直接返回。如果没有,查询数据库。

  4. 证明一级缓存的存在,通过用户id查询2次,查看结果。

     测试代码:

 @Testpublic void findById() {User user1 = mapper.findById(1);System.out.println(user1);User user2 = mapper.findById(1);System.out.println(user2);}

 结果:

 此时我们发现,这里只有一条sql查询语句,说明第一次是通过数据库查询到的信息,而第二次没有查询数据库,直接就显示了信息,说明信息是从缓存获得的

再直观一点:清理session的缓存再进行信息查询

测试代码:

   @Testpublic void findById() {User user1 = mapper.findById(1);System.out.println(user1);//清理掉之前缓存的数据session.clearCache();User user2 = mapper.findById(1);System.out.println(user2);}

结果:

显而易见,缓存消失,查询了两次数据库 

5.一级缓存的原理分析

  1.一级缓存底层使用的是Map集合,key存储的是执行的SQL语句,value存放的是查询的对象
2.BaseExecutor类的152行源码地方先查询缓存,再查询数据库
3.一级缓存的生命周期和SlSession的生命周期相同,SalSession对象关闭,一级缓存也会关闭。
1.session.clearCache()调用该方法可以清空缓存
2.调用调用SalSession的update、insert、delete、commit和close等方法的时候也会清
空缓存。

3. MyBatis的二级缓存

1.二级缓存是全局缓存,范围跨越多个SqlSession,可以再不同的Mapper之间共享

2.应用启动时创建,应用关闭时销毁

3.缓存对象必须实现Serializable接口

2.1二级缓存的配置步骤:

 1.全局启用二级缓存(Mybatis总配置文件里)

<settings><setting name="cacheEnabled" value="true"/> <!-- 必须设置为 true -->
</settings>

2.在Mapper中声明缓存 


2.2测试代码 
import com.qcby.entity.User;
import com.qcby.mapper.AccountMapper;
import com.qcby.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;import java.io.IOException;
import java.io.InputStream;
import java.util.List;public class UserTest {private InputStream in;private SqlSessionFactory factory;@Beforepublic void init() throws Exception {// 加载配置文件in = Resources.getResourceAsStream("SqlMap.xml");// 创建工厂对象factory = new SqlSessionFactoryBuilder().build(in);System.out.println("执行开始");}@Afterpublic void destory() throws IOException {in.close();System.out.println("执行结束");}
//    @Test
//    public void findOneToMany() {
//        List<User> users = mapper.findOneToMany();
//        for (User user : users) {
//            System.out.println(user);
//        }
//    }@Testpublic void findById() {SqlSession session = factory.openSession();UserMapper mapper = session.getMapper(UserMapper.class);User user1 = mapper.findById(1);System.out.println(user1);session.close();SqlSession session2 = factory.openSession();UserMapper mapper1 = session2.getMapper(UserMapper.class);User user2 = mapper1.findById(1);System.out.println(user2);session.close();}
}

 

两次查询获取到的不是同一个对象,说明是第个信息是从二级缓存中获取的

4.二级缓存工作流程

  1. 第一次查询 (user1):

    • 查询数据库获取数据

    • 将结果存入一级缓存(SqlSession级别)

    • session.close()时,一级缓存内容会序列化后存入二级缓存(SqlSessionFactory级别)

  2. 第二次查询 (user2):

    • 新Session首先检查自己的一级缓存 → 没有(因为是新Session)

    • 检查二级缓存 → 找到缓存数据

    • 将缓存数据反序列化后创建新对象返回

    • 不会访问数据库(这就是为什么对象不同但数据相同)

感谢您的观看

http://www.dtcms.com/a/276265.html

相关文章:

  • 电网失真下单相锁相环存在的问题
  • STM32第二十一天定时器TIM
  • docker搭建 与镜像加速器
  • LeetCode经典题解:3、无重复字符的最长子串
  • 【Elasticsearch】post_filter
  • 【MATLAB代码】Chan方法解算TOA,用于三维目标的定位,锚点数量可自适应。订阅专栏后可查看完整代码
  • Windows环境下解决Matplotlib中文字体显示问题的详细指南
  • PyTorch神经网络实战:从零构建图像分类模型
  • linux----------------------线程同步与互斥(上)
  • 搭建MySQL读写分离
  • LiteFlow源码
  • Mamba架构的模型 (内容由deepseek辅助汇总)
  • 手把手教你 Aancond 的下载与 YOLOV13 部署(环境的创建及配置下载)以及使用方法,连草履虫都能学会的目标检测实验!
  • net.createServer详解
  • Python后端项目之:我为什么使用pdm+uv
  • 模拟注意力:少量参数放大 Attention 表征能力
  • hiredis: 一个轻量级、高性能的 C 语言 Redis 客户端库
  • 深入解析C#接口实现的两种核心技术:派生继承 vs 显式实现
  • Java 21 虚拟线程
  • 浏览器宏任务的最小延时:揭开setTimeout 4ms的神话
  • java中的main方法
  • window7,windows10,windows11种系统之间实现打印机共享
  • 创客匠人:从定位逻辑看创始人 IP 如何驱动 IP 变现
  • CompareFace使用
  • Kimi K2万亿参数开源模型原理介绍
  • 【读书笔记】《C++ Software Design》第二章:The Art of Building Abstractions
  • Ruby如何采集直播数据源地址
  • OpenEuler操作系统中检测插入的USB设备并自动挂载
  • 【数据结构】反射、枚举 和 lambda表达式
  • Golang 面向对象(封装、继承、多态)