news 2026/8/9 9:55:04

第9章:MyBatis多级缓存和懒加载

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
第9章:MyBatis多级缓存和懒加载

文章目录

  • 第9章:MyBatis多级缓存和懒加载
    • 一级缓存
    • 二级缓存怎么使用
    • 懒加载

第9章:MyBatis多级缓存和懒加载

一级缓存

什么是缓存?

一级缓存核心定位

  • 一级缓存是 MyBatis 内置的默认缓存机制,无需手动配置,默认开启。
  • 作用域:
    • 仅限当前SqlSession(数据库会话)
    • 不同 SqlSession 之间的缓存相互隔离。
  • 缓存介质:
  • 内存(基于HashMap存储),缓存键由Mapper ID + SQL 语句 + 参数 + 分页信息 + 环境信息组成。

核心价值:

  • 减少同一 SqlSession 内重复查询的数据库交互,提升查询性能。

  • 一级缓存生效与失效条件

    场景类型生效条件失效条件
    核心前提同一 SqlSession、相同 Mapper ID+SQL + 参数不同 SqlSession、SQL / 参数 / 分页不同
    数据库操作影响未执行增删改(insert/update/delete)操作执行增删改操作(自动清空当前 SqlSession 缓存)
    手动干预未调用clearCache()close()方法调用sqlSession.clearCache()(手动清空)、sqlSession.close()(关闭会话)
    配置影响默认配置(无特殊禁用)全局配置localCacheScope=STATEMENT(禁用一级缓存)

一级缓存工作流程

一级缓存核心特性:

@Service@Slf4jpublicclassUserService{@AutowiredprivateSqlSessionTemplatesqlSessionTemplate;/*一级缓存 有效的访问*/publicvoidfirstCache(){SqlSessionFactorysqlSessionFactory=sqlSessionTemplate.getSqlSessionFactory();SqlSessionsqlSession=sqlSessionFactory.openSession();UserMapperuserMapper=sqlSession.getMapper(UserMapper.class);Useruser=userMapper.selectById(1);log.info("第一次查询结果:{}",user);Useruser2=userMapper.selectById(1);log.info("第二次查询结果:{}",user2);log.info("两个user是否是同一个对象:{}",user==user2);sqlSession.close();}/*一级缓存 失效的访问*/publicvoidfirstCacheInvalidation(){SqlSessionFactorysqlSessionFactory=sqlSessionTemplate.getSqlSessionFactory();SqlSessionsqlSession=sqlSessionFactory.openSession();UserMapperuserMapper=sqlSession.getMapper(UserMapper.class);Useruser=userMapper.selectById(1);log.info("第一次查询结果:{}",user);/*执行 写的操作*/user.setAge(18);introws=userMapper.update(user);log.info("执行写的操作,影响行数:{}",rows);//清空缓存// sqlSession.clearCache();Useruser2=userMapper.selectById(1);log.info("第二次查询结果:{}",user2);log.info("两个user是否是同一个对象:{}",user==user2);sqlSession.close();}}

二级缓存怎么使用

核心概念界定

二级缓存核心定位

  • 二级缓存(Mapper 级缓存)是 MyBatis 的跨 SqlSession 缓存
    • 作用域为同一个 Mapper(namespace)
    • 不同 SqlSession 可共享缓存数据。
  • 缓存介质:
    • 默认内存(HashMap),支持自定义(如 Redis等第三方缓存)
  • 核心价值:
    • 减少不同 SqlSession 间重复查询的数据库交互
    • 适用于查询频率高、修改频率低的数据(如字典表、配置表)
  • 依赖条件:实体类需实现Serializable接口,需手动开启

一级缓存与二级缓存核心区别

对比维度一级缓存(SqlSession 级)二级缓存(Mapper 级)
作用域单个 SqlSession同一个 Mapper(namespace)
共享性不可跨 SqlSession 共享可跨 SqlSession 共享
开启方式默认开启,无需配置需全局配置 + Mapper 配置手动开启
实体类要求无强制序列化要求必须实现 Serializable 接口
失效触发同一 SqlSession 内增删改、clearCache ()对应 Mapper 内增删改操作、缓存过期等
适用场景单会话内重复查询多会话共享高频查询数据

二级缓存工作流程

二级缓存开启条件(三步缺一不可)

  • 全局配置开启:
    • springBoot 配置文件中设置cacheEnabled=true
  • Mapper 级开启:
    • 在 Mapper XML 中添加<cache/>标签
  • 实体类序列化:
    • 缓存的实体类必须实现java.io.Serializable接口(避免序列化异常)。

二级缓存配置详解

mybatis:configuration:cache-enabled:true# 启用二级缓存
<!-- Mapper XML 中配置二级缓存 --><mappernamespace="com.example.mapper.UserMapper"><!-- 开启二级缓存配置 --><cacheeviction="LRU"flushInterval="60000"size="512"readOnly="true"/><selectid="selectUserById"parameterType="long"resultType="User"useCache="true">SELECT * FROM user WHERE id = #{id}</select></mapper>

二级缓存属性详解表

属性可选值默认值说明
evictionLRU/FIFO/SOFT/WEAKLRU缓存回收策略
flushInterval毫秒数缓存刷新间隔
size正整数1024缓存引用数量
readOnlytrue/falsefalse是否只读
blockingtrue/falsefalse是否使用阻塞缓存

常见的缓存回收策略:

策略缩写全称策略说明
LRULeast Recently Used移除最长时间未被使用的对象(默认策略)。
FIFOFirst In First Out按对象进入缓存的顺序来移除它们。
SOFTSoft Reference基于垃圾回收器状态和软引用规则来移除对象。
WEAKWeak Reference更积极地基于垃圾收集器状态和弱引用规则移除对象。
// 使用二级缓存需要实体类实现Serializable接口@Data@NoArgsConstructor@AllArgsConstructorpublicclassUserimplementsSerializable{privateLongid;privateStringusername;privateStringemail;privateIntegerage;privateDatecreateTime;privateDateupdateTime;// 关联对象也需要序列化}
// 二级缓存服务演示@Service@Slf4jpublicclassSecondLevelCacheService{@AutowiredprivateUserMapperuserMapper;/** * 演示二级缓存跨SqlSession共享 */publicvoiddemonstrateSecondLevelCache(){Useruser1=userMapper.selectUserById(1L);log.info("SqlSession查询: {}",user1);// 重新调用方法模拟第二个SqlSession(实际应用中可能是另一个请求)log.info("=== 二级缓存演示结束 ===");}/** * 二级缓存失效场景 */publicvoiddemonstrateSecondLevelCacheInvalidation(){// 执行更新操作Useruser1=newUser();user1.setId(1L);user1.setEmail("newemail@example.com");intupdateCount=userMapper.updateUser(user1);log.info("更新影响行数: {}",updateCount);}}

懒加载

懒加载核心定位

  • 懒加载(延迟加载)是 MyBatis 关联查询的性能优化机制
    • 指查询主对象时,不立即加载关联对象
    • 而是在首次访问关联对象时才触发查询xa
  • 对立概念:
    • 立即加载(默认行为),查询主对象时同时加载所有关联对象
  • 核心价值:
    • 避免不必要的关联查询,
    • 减少数据库压力
    • 如仅需查询用户基本信息时,无需加载其所有订单
  • 适用场景:
    • 一对一、一对多、多对多关联查询,且关联数据不总是需要使用

懒加载与立即加载对比

懒加载开启条件

  • 全局配置开启延迟加载:
    • lazyLoadingEnabled=true(默认 false)
  • 关闭积极加载:
    • aggressiveLazyLoading=false
    • SpringBoot 2.x+ 已默认关闭,确保按需加载
  • 关联标签配置(可选):
    • associationcollection标签添加fetchType="lazy"(优先级高于全局配置)

懒加载配置详解

mybatis:configuration:lazy-loading-enabled:true# 开启全局懒加载aggressive-lazy-loading:false# 关闭积极加载(按需加载)map-underscore-to-camel-case:true

懒加载实战案例

<!-- 基础用户结果映射(不包含关联对象) --><resultMapid="BaseUserMap"type="com.example.entity.User"><idcolumn="user_id"property="userId"/><resultcolumn="user_name"property="userName"/><resultcolumn="card_id"property="cardId"/></resultMap><!-- 嵌套查询结果映射:使用子查询方式加载关联对象 --><resultMapid="UserWithIdCardNestedQueryMap"type="com.example.entity.User"extends="BaseUserMap"><associationproperty="idCard"column="card_id"select="com.example.mapper.IdCardMapper.selectById"javaType="com.example.entity.IdCard"fetchType="lazy"/></resultMap><!-- 嵌套查询方式:查询用户(触发子查询加载身份证) --><selectid="selectUserWithIdCardNested"resultMap="UserWithIdCardNestedQueryMap">SELECT user_id, user_name, card_id FROM t_user WHERE user_id = #{userId}</select>

懒加载最佳实践

  • 适用场景:

    • 关联数据量大,且不经常使用
    • 需要快速响应的列表查询
    • 移动端应用,减少数据传输
  • 注意事项:
    ) -->

    SELECT
    user_id,
    user_name,
    card_id
    FROM t_user
    WHERE user_id = #{userId}

懒加载最佳实践 - 适用场景: - 关联数据量大,且不经常使用 - 需要快速响应的列表查询 - 移动端应用,减少数据传输 - 注意事项: - 注意 N+1 查询问题
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/7 17:22:00

打破传统桎梏,LLM 让智能运维实现从 “自动化” 到 “自进化”

引言&#xff1a;复杂系统下的运维困境与LLM破局契机 在数字化浪潮的推动下&#xff0c;微服务、云原生、容器化等技术已深度融入软件系统的构建与运行全流程。这些技术的普及让系统功能更加强大、部署更加灵活&#xff0c;但同时也让系统架构变得愈发复杂。曾经单一服务器就能…

作者头像 李华
网站建设 2026/8/7 16:40:04

好写作AI:降重不疯魔,润色不尴尬!AI“精装修”你的毕业论文

各位正在与查重报告进行殊死搏斗、同时被导师批“语言像白话”的毕业生们&#xff0c;你们好&#xff01;是不是感觉论文写到这步&#xff0c;已经不是在比谁更有智慧&#xff0c;而是在比谁更会“改写”和“说话”&#xff1f;别急&#xff0c;你的论文“精装修”队长——好写…

作者头像 李华
网站建设 2026/7/31 4:53:53

cuas ai相关论文 Awesome-Efficient-Agents

yxf203/Awesome-Efficient-Agents: 关于效率引导的 LLM 代理的综述和论文列表&#xff08;记忆、工具学习、规划&#xff09;。 --- yxf203/Awesome-Efficient-Agents: Survey and paper list on efficiency-guided LLM agents (memory, tool learning, planning).

作者头像 李华
网站建设 2026/8/8 6:42:58

【大数据毕设全套源码+文档】基于Django+协同过滤算法的电影个性化推荐系统的设计与实现(丰富项目+远程调试+讲解+定制)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/8/9 11:30:28

基于Python 医药信息管理系统(源码+数据库+文档)

医药信息管理 目录 基于PythonDjango医药信息管理系统 一、前言 二、系统功能演示 三、技术选型 四、其他项目参考 五、代码参考 六、测试参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a; 基于PythonDjango医药信息管理系统 一、前言 博主介绍&#xff1a…

作者头像 李华
网站建设 2026/8/9 5:45:59

1小时搞定:用PLAYWRIGHT快速验证产品创意

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个快速验证产品创意的PLAYWRIGHT原型&#xff0c;功能包括&#xff1a;1.自动采集竞品关键页面截图 2.提取核心功能点对比 3.生成可视化对比报告 4.模拟用户旅程。要求支持配…

作者头像 李华