JAVA:MyBatis 缓存机制详解的技术指南

news2025/1/20 14:48:15

1、简述

MyBatis是Java开发中常用的持久层框架之一,通过面向对象的方式操作数据库。为了提高系统性能,MyBatis提供了两级缓存机制:一级缓存(本地缓存)和二级缓存(全局缓存)。本文将详细讲解MyBatis缓存机制的使用原理、配置方法,并通过示例展示如何合理地使用缓存优化数据访问效率。

在这里插入图片描述

2、基础原理

2.1 一级缓存
  • 作用范围:一级缓存是基于SqlSession级别的缓存,即在同一个SqlSession中执行的相同SQL语句将会从缓存中获取结果,而不会再去查询数据库。
  • 存储方式:一级缓存的默认存储机制是基于HashMap实现的。
  • 特点:默认开启,无法跨SqlSession共享数据,查询范围有限。
2.2 二级缓存
  • 作用范围:二级缓存是基于Mapper级别的缓存,即同一个命名空间的Mapper都可以共享二级缓存。
  • 存储方式:MyBatis默认使用PerpetualCache作为二级缓存,使用HashMap进行存储。
  • 特点:二级缓存是可选的,需要在配置文件中开启,支持多个SqlSession共享同一数据,能够有效减少数据库查询次数。

3、一级缓存的使用

一级缓存默认开启,无需额外配置。当执行同一查询时,MyBatis会先检查一级缓存,若存在结果则直接返回缓存数据,否则才会执行SQL查询数据库。

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import com.example.mapper.UserMapper;
import com.example.model.User;

public class MyBatisCacheDemo {

    public static void main(String[] args) {
        SqlSessionFactory sqlSessionFactory = MyBatisUtil.getSqlSessionFactory();

        try (SqlSession session = sqlSessionFactory.openSession()) {
            UserMapper userMapper = session.getMapper(UserMapper.class);

            // 第一次查询
            User user1 = userMapper.selectUserById(1);
            System.out.println("第一次查询:" + user1);

            // 第二次查询,触发一级缓存
            User user2 = userMapper.selectUserById(1);
            System.out.println("第二次查询(来自缓存):" + user2);

            // 判断是否为同一对象
            System.out.println("是否为同一对象:" + (user1 == user2));  // true
        }
    }
}

注意:如果执行了session.commit()、session.close()、session.clearCache()等操作,一级缓存将会失效。

4、二级缓存的配置与使用

MyBatis默认关闭二级缓存,需要在mybatis-config.xml或Mapper映射文件中开启。

4.1 在全局配置文件中开启二级缓存

在mybatis-config.xml中增加true,如:

<configuration>
    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>
</configuration>
4.2 在Mapper XML文件中配置二级缓存

在具体的Mapper文件中加入标签来启用二级缓存。

<mapper namespace="com.example.mapper.UserMapper">
    <cache/>
    
    <select id="selectUserById" parameterType="int" resultType="com.example.model.User">
        SELECT * FROM user WHERE id = #{id}
    </select>
</mapper>
4.3 使用二级缓存示例
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import com.example.mapper.UserMapper;
import com.example.model.User;

public class MyBatisCacheDemo {

    public static void main(String[] args) {
        SqlSessionFactory sqlSessionFactory = MyBatisUtil.getSqlSessionFactory();

        // 第一次查询,开启第一个SqlSession
        try (SqlSession session1 = sqlSessionFactory.openSession()) {
            UserMapper userMapper1 = session1.getMapper(UserMapper.class);
            User user1 = userMapper1.selectUserById(1);
            System.out.println("第一次查询:" + user1);
        } // SqlSession关闭,触发二级缓存存储

        // 第二次查询,开启新的SqlSession
        try (SqlSession session2 = sqlSessionFactory.openSession()) {
            UserMapper userMapper2 = session2.getMapper(UserMapper.class);
            User user2 = userMapper2.selectUserById(1);
            System.out.println("第二次查询(来自二级缓存):" + user2);

            // 判断是否为同一对象
            System.out.println("是否为同一对象:" + (user1 == user2));  // true
        }
    }
}

5、缓存失效的场景

在以下情况下,MyBatis的缓存将会失效:

  • 增删改操作:每当执行INSERT、UPDATE或DELETE操作后,一级缓存和二级缓存都会失效。
  • 手动清空缓存:可以通过SqlSession.clearCache()方法手动清空一级缓存。
  • 不同SqlSession:一级缓存仅作用于当前SqlSession,不同SqlSession之间无法共享一级缓存。
  • 其他影响因素:MyBatis中mapper.xml文件中的flushCache配置项等也会影响缓存策略。

缓存的优缺点分析:

  • 优点
    提升性能:缓存机制减少了数据库的交互次数,提升了查询效率。
    简化数据共享:特别是二级缓存,多个SqlSession可以共享数据,适合不经常变动的数据。
  • 缺点
    缓存不一致:数据库数据变动后,可能会造成缓存数据不一致的问题。
    占用内存:大量的数据缓存可能会导致内存占用过高。
    适用场景有限:频繁变动的数据不适合缓存。

6、总结

MyBatis的缓存机制是一种有效的数据访问优化方案。通过一级缓存和二级缓存,开发者可以显著减少数据库查询次数,提升系统的性能。在实际使用中,需要合理配置和使用缓存机制,特别是在数据变动频繁的情况下,可以适当关闭缓存或手动清空缓存,保证数据的一致性。

MyBatis缓存的使用场景建议:

  • 适用于读取频率高且修改较少的数据,如产品信息、用户基本资料等。
  • 对于频繁变更的数据,如订单、库存信息等,建议关闭缓存,以避免缓存不一致的问题。

通过合适的缓存配置和控制策略,MyBatis缓存机制可以为系统带来显著的性能提升。希望本文的示例和介绍对您在项目中使用MyBatis缓存有所帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2279405.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前后端分离的Java快速开发平台

采用SpringBoot3.x、Shiro、MyBatis-Plus、Vue3、TypeScript、Element Plus、Vue Router、Pinia、Axios、Vite框架&#xff0c;开发的一套权限系统&#xff0c;极低门槛&#xff0c;拿来即用。设计之初&#xff0c;就非常注重安全性&#xff0c;为企业系统保驾护航&#xff0c;…

数据结构:栈和队列详解(上)

一.栈 1.概念与结构&#xff1a; 栈&#xff1a;一种特殊的线性表&#xff0c;只允许在顺序表的一段插入和删除数据&#xff0c;进行插入和删除的一端叫做栈顶&#xff0c;另外一端则叫做栈底&#xff0c;而我们将在栈顶插入数据叫做压栈&#xff08;入栈或进栈&#xff09;&a…

初识go语言之指针用法

一、环境准备 安装go语言编译环境&#xff0c;官网地址&#xff1a;https://go.dev/dl/ 或者 https://golang.google.cn/dl/ 点击下载按提示安装即可 vscode 安装go语言扩展 测试 package mainimport "fmt"func main() {fmt.Println("Hello, World!") …

python(25) : 含有大模型生成的公式的文本渲染成图片并生成word文档(支持flask接口调用)

公式样例 渲染前 \[\sqrt{1904.615384} \approx 43.64\] 渲染后 安装依赖 pip install matplotlib -i https://mirrors.aliyun.com/pypi/simple/ requestspip install sympy -i https://mirrors.aliyun.com/pypi/simple/ requestspip install python-docx -i https://mirro…

国产文本编辑器EverEdit - 恢复最近的选区

1 恢复最近的选区 1.1 应用场景 如果用户选择了一些文本&#xff0c;特别是多选区选择&#xff0c;在选择的过程中出现失误&#xff0c;导致选区丢失&#xff0c;一般的做法是骂骂咧咧再选一次&#xff0c;使用EverEdit就没有这个烦恼&#xff0c;EverEdit内置了恢复最近的选区…

54,【4】BUUCTF WEB GYCTF2020Ezsqli

进入靶场 吓我一跳&#xff0c;但凡放个彭于晏我都不说啥了 提交个1看看 1 and 11 1# 还尝试了很多&#xff0c;不过都被过滤了&#xff0c;头疼 看看别人的WP 竟然要写代码去跑&#xff01;&#xff01;&#xff01;&#xff0c;不会啊&#xff0c;先用别人的代码吧&#xf…

【unity进阶篇】unity如何实现跨平台及unity最优最小包体打包方式(.NET、Mono和IL2CPP知识介绍)

考虑到每个人基础可能不一样&#xff0c;且并不是所有人都有同时做2D、3D开发的需求&#xff0c;所以我把 【零基础入门unity游戏开发】 分为成了C#篇、unity通用篇、unity3D篇、unity2D篇。 【C#篇】&#xff1a;主要讲解C#的基础语法&#xff0c;包括变量、数据类型、运算符、…

实力认证 | 海云安入选《信创安全产品及服务购买决策参考》

近日&#xff0c;国内知名安全调研机构GoUpSec发布了2024年中国网络安全行业《信创安全产品及服务购买决策参考》&#xff0c;报告从产品特点、产品优势、成功案例、安全策略等维度对各厂商信创安全产品及服务进行调研了解。 海云安凭借AI大模型技术在信创安全领域中的创新应用…

联想装系统后触摸板无法设置双指手势

我的一个电脑是联想小新air13&#xff0c;装Windows10系统后&#xff0c;没有找到设置触摸板手势的地方 也没有“装置设定值” 这个选项 经查询&#xff0c;需要去联想网站搜索驱动&#xff0c;下载了一个“Lenovo联想驱动管理” &#xff0c;更新了下触摸板驱动&#xff0c; …

ue5 制作,播放,停止动画蒙太奇

右键&#xff0c;动画蒙太奇 新建插槽 把默认插槽选择为&#xff0c;自己新建的插槽 然后拖一个动画进去 input换成玩家0 就可以接收键盘事件 pawn 自动控制玩家换成玩家0 找到动画蓝图 把它化成我们那边蒙太奇里面的槽 第三步&#xff1a;第三人称角色蓝图 按下F…

一文大白话讲清楚webpack基本使用——1——完成webpack的初步构建

文章目录 一文大白话讲清楚webpack基本使用——1——完成webpack的初步构建1. 先回忆webpack是个啥2. webpack四大核心2.1 Entry(入口)2.2 Output(输出)2.3 Loader(加载器)2.4 Plugin(插件) 3. 按部就班实现webpack3.1 初始化项目3.2 完成项目骨架搭建3.3 实现webpack构建 一文…

迁移学习-详解

一、fasttext工具介绍 1 fasttext介绍 1.1 fasttext作用 作为NLP工程领域常用的工具包, fasttext有两大作用: 进行文本分类 训练词向量 1.2 fasttext工具包的优势 正如它的名字, 在保持较高精度的情况下, 快速的进行训练和预测是fasttext的最大优势. fasttext优势的原因:…

Mac 删除ABC 输入法

参考链接&#xff1a;百度安全验证 Mac下删除系统自带输入法ABC&#xff0c;正解&#xff01;_mac删除abc输入法-CSDN博客 ABC 输入法和搜狗输入法等 英文有冲突~~ 切换后还会在英文状态&#xff0c;可以删除 &#xff1b;可能会对DNS 输入有影响&#xff0c;但是可以通过复…

读取GPS文件中的坐标

不同厂家产生的gps不同&#xff0c;但MALA, impulse等厂家还是比较规范&#xff0c;格式基本一致。 1 格式对比 厂家1&#xff1a;128930 1 31.865250637 118.631077136 -87.226619530 -17.247052234 -20.881583506 -19.300643625 9.146650245 -5.089975857 4.000000000 2024…

【github 使用相关】GitHub Desktop桌面端基础操作 WIP 分支 提交pr

WIP 是 “Work In Progress”&#xff08;进行中的工作&#xff09;的缩写&#xff0c;WIP分支通常用来存放尚未完成或不稳定的代码&#xff0c;开发者可在WIP进行实验逐步完成某项功能、进行团队开发、修复重要BUG和多任务处理。 在 GitHub Desktop 上管理 WIP&#xff08;Wo…

C语言之装甲车库车辆动态监控辅助记录系统

&#x1f31f; 嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 C语言之装甲车库车辆动态监控辅助记录系统 目录 一、前言 1.1 &#xff08;一&#xff09;…

日志模块新增配置日志根目录和项目模块功能

文章目录 1.日志模块新增监听器支持外部配置1.common-log4j2-starter项目结构2.修改log4j2.xml为log4j2-spring.xml&#xff08;这样可以解决读取外部配置但是提前创建目录的问题&#xff09;3.ApplicationEnvironmentPreparedListener.java 监听器读取配置4.spring.factories …

[JavaScript] 运算符详解

文章目录 算术运算符&#xff08;Arithmetic Operators&#xff09;注意事项&#xff1a; 比较运算符&#xff08;Comparison Operators&#xff09;注意事项&#xff1a; 逻辑运算符&#xff08;Logical Operators&#xff09;短路运算&#xff1a;逻辑运算符的返回值&#xf…

latin1_swedish_ci(latin1 不支持存储中文、日文、韩文等多字节字符)

文章目录 1、SHOW TABLE STATUS WHERE Name batch_version;2、latin1_swedish_ci使用场景注意事项修改字符集和排序规则修改表的字符集和排序规则修改列的字符集和排序规则修改数据库的默认字符集和排序规则 3、ALTER TABLE batch_version CONVERT TO CHARACTER SET utf8mb4 C…

【机器学习实战入门】使用OpenCV进行性别和年龄检测

Gender and Age Detection Python 项目 首先,向您介绍用于此高级 Python 项目的性别和年龄检测中的术语: 什么是计算机视觉? 计算机视觉是一门让计算机能够像人类一样观察和识别数字图像和视频的学科。它面临的挑战大多源于对生物视觉有限的了解。计算机视觉涉及获取、处…