新闻详情

新闻详情

首页 / 资讯中心 / 详情

Mybatis高级进阶

发布时间:2026/10/2 12:52:39来源:尧图网络
Mybatis高级进阶
一、引言在完成 MyBatis 基础 CRUD 与配置学习之后我们进入更核心的进阶阶段。本篇文章聚焦两大主题高级核心特性动态 SQL、复杂关联映射、缓存机制与生态整合与工程化落地Spring 原生整合、SpringBoot 3.x 自动整合、工程化工具提效。掌握这些能力你就能从容应对复杂业务场景并顺利融入企业级项目开发流程。二、高级核心特性本阶段目标掌握 MyBatis 核心高级能力应对复杂业务场景开发。2.1 动态 SQL 全语法实战#{}与${}的区别面试高频在动态 SQL 中#{}与${}是两种不同的参数占位方式理解它们的区别对安全与性能至关重要#{}预编译占位符MyBatis 会将其替换为?通过PreparedStatement预编译后传入参数能有效防止 SQL 注入是推荐使用的方式。${}字符串拼接MyBatis 会直接将参数值拼接到 SQL 语句中不做预编译存在 SQL 注入风险仅适用于表名、列名、排序字段等无法使用占位符的场景。!-- #{} 预编译安全 --selectidfindByNameresultTypeUserSELECT * FROM user WHERE name #{name}/select!-- ${} 字符串拼接仅用于表名/列名/排序等 --selectidselectByOrderresultTypeUserSELECT * FROM ${tableName} ORDER BY ${orderColumn}/select对比项#{}${}预编译是?占位否直接拼接SQL 注入风险无有适用场景值参数where 条件、insert 值等表名、列名、排序字段推荐程度优先使用谨慎使用动态 SQL 是 MyBatis 最强大的特性之一它让我们可以在 XML 中编写灵活的条件查询与更新语句避免拼接 SQL 的繁琐与安全隐患。核心标签if、choose/when/otherwiseif标签用于实现多条件动态拼接当条件成立时将标签内的 SQL 片段拼接到主语句中selectidfindByConditionresultTypeUserSELECT * FROM user WHERE 1 1iftestname ! null and name ! AND name #{name}/ififtestemail ! nullAND email #{email}/if/selectchoose/when/otherwise类似于 Java 中的switch用于「多选一」的场景只会命中第一个满足条件的分支selectidfindByPriorityresultTypeUserSELECT * FROM user WHERE status 1choosewhentestpriority highAND level 3/whenwhentestpriority mediumAND level 2/whenotherwiseAND level 1/otherwise/choose/select简化标签where、set手动书写WHERE 1 1并不优雅。where标签会自动处理 SQL 拼接后的多余AND、OR关键字selectidfindByConditionresultTypeUserSELECT * FROM userwhereiftestname ! null and name ! AND name #{name}/ififtestemail ! nullAND email #{email}/if/where/selectset标签用于动态更新语句自动处理多余逗号updateidupdateUserUPDATE usersetiftestname ! nullname #{name},/ififtestemail ! nullemail #{email},/if/setWHERE id #{id}/update批量操作foreachforeach标签支持批量插入、批量查询大幅提升数据操作效率。批量插入示例insertidbatchInsertINSERT INTO user (name, email) VALUESforeachcollectionlistitemitemseparator,(#{item.name}, #{item.email})/foreach/insert批量查询IN 条件示例selectidselectByIdsresultTypeUserSELECT * FROM user WHERE id INforeachcollectionidsitemidopen(close)separator,#{id}/foreach/select进阶技巧sql/includesql标签用于抽取公共 SQL 片段include用于引用实现代码复用sqliduserColumnsid, name, email, create_time/sqlselectidselectAllresultTypeUserSELECTincluderefiduserColumns/FROM user/select2.2 复杂关联映射一对一关联association通过association完成用户-用户档案的关联映射resultMapidUserWithProfileMaptypeUseridpropertyidcolumnid/resultpropertynamecolumnname/associationpropertyprofilejavaTypeUserProfileidpropertyidcolumnprofile_id/resultpropertyaddresscolumnaddress//association/resultMap一对多关联collection通过collection完成部门-员工列表的集合映射resultMapidDeptWithEmpsMaptypeDepartmentidpropertyidcolumnid/resultpropertynamecolumnname/collectionpropertyemployeesofTypeEmployeeidpropertyidcolumnemp_id/resultpropertynamecolumnemp_name//collection/resultMap嵌套查询 vs 嵌套结果关联映射有两种实现方式需要根据场景权衡嵌套查询先查主表再根据外键逐条发起子查询。实现简单但可能触发多次查询产生N1 查询问题。嵌套结果通过一条 JOIN SQL 一次查出所有数据由 MyBatis 完成结果映射。性能更优是生产环境的推荐选择。!-- 嵌套结果一条 JOIN 查出所有数据 --selectidselectDeptWithEmpsresultMapDeptWithEmpsMapSELECT d.id, d.name, e.id AS emp_id, e.name AS emp_name FROM department d LEFT JOIN employee e ON d.id e.dept_id WHERE d.id #{id}/select2.3 缓存机制原理与实战一级缓存一级缓存是SqlSession 级别的缓存默认开启。同一 SqlSession 内重复查询会命中缓存避免重复访问数据库。需要注意的失效场景执行增删改操作后缓存会被清空手动调用sqlSession.clearCache()会清空缓存不同 SqlSession 之间不共享一级缓存。try(SqlSessionsessionsqlSessionFactory.openSession()){Useruser1session.selectOne(selectUser,1);Useruser2session.selectOne(selectUser,1);// 命中一级缓存System.out.println(user1user2);// true}二级缓存二级缓存是Mapper 级别的缓存跨 SqlSession 共享。开启方式是在 Mapper XML 中添加配置cacheevictionLRUflushInterval60000size512readOnlytrue/使用二级缓存需要注意生产避坑点脏数据问题多表关联查询时若另一张表的数据被修改缓存不会自动失效可能读到脏数据序列化要求缓存对象需要实现Serializable接口readOnlyfalse时建议仅在查询频率高、数据变更少的场景开启。缓存失效场景分析场景一级缓存二级缓存同一 SqlSession 重复查询命中命中跨 SqlSession 查询不命中命中执行增删改清空清空默认手动 clearCache()清空不清空理解这些失效场景能有效避免业务中出现脏数据问题。三、生态整合与工程化落地本阶段目标对接 Spring/SpringBoot融入企业级项目开发流程。3.1 Spring 原生整合 MyBatis整合核心依赖原生整合需要引入mybatis-spring与spring-jdbc依赖dependencygroupIdorg.mybatis/groupIdartifactIdmybatis-spring/artifactIdversion3.0.3/version/dependencydependencygroupIdorg.springframework/groupIdartifactIdspring-jdbc/artifactIdversion6.1.0/version/dependency配置 SqlSessionFactoryBean配置SqlSessionFactoryBean注入数据源实现配置文件与 Spring 容器的融合beanidsqlSessionFactoryclassorg.mybatis.spring.SqlSessionFactoryBeanpropertynamedataSourcerefdataSource/propertynamemapperLocationsvalueclasspath:mapper/*.xml/propertynametypeAliasesPackagevaluecom.demo.entity//bean配置 MapperScannerConfigurer配置MapperScannerConfigurer自动批量扫描 Mapper 接口并注入 Spring 容器beanclassorg.mybatis.spring.mapper.MapperScannerConfigurerpropertynamebasePackagevaluecom.demo.mapper/propertynamesqlSessionFactoryBeanNamevaluesqlSessionFactory//bean理解 SqlSessionTemplateSqlSessionTemplate是 MyBatis-Spring 的核心它具备线程安全特性替代原生 SqlSession 实现自动管理无需手动关闭资源AutowiredprivateSqlSessionTemplatesqlSessionTemplate;publicUserfindUser(Longid){returnsqlSessionTemplate.selectOne(com.demo.mapper.UserMapper.selectById,id);}3.2 SpringBoot 3.x 自动整合引入起步依赖引入mybatis-spring-boot-starter起步依赖实现零 XML 快速配置dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion3.0.3/version/dependencyapplication.yml 配置在application.yml中配置 MyBatis 参数Mapper 路径、别名包、驼峰映射等mybatis:mapper-locations:classpath:mapper/*.xmltype-aliases-package:com.demo.entityconfiguration:map-underscore-to-camel-case:true理解 MybatisAutoConfigurationMybatisAutoConfiguration是 SpringBoot 自动配置的核心类它会在应用启动时自动完成以下工作读取mybatis.*配置项自动创建SqlSessionFactoryBean自动扫描Mapper注解的接口并注册为 Bean自动注入SqlSessionTemplate。SpringBootApplicationMapperScan(com.demo.mapper)publicclassApplication{publicstaticvoidmain(String[]args){SpringApplication.run(Application.class,args);}}3.3 工程化工具提效MyBatisX 插件MyBatisX 是 IDEA 中的高效插件支持一键生成 Mapper 接口、XML、实体类在 Mapper 接口与 XML 之间快速跳转关联代码提供代码补全与语法校验。MyBatis Generator 逆向工程MyBatis Generator 根据数据库表自动生成基础 CRUD 代码减少重复劳动generatorConfigurationcontextidmysqltargetRuntimeMyBatis3SimplejdbcConnectiondriverClasscom.mysql.cj.jdbc.DriverconnectionURLjdbc:mysql://localhost:3306/demouserIdrootpassword123456/javaModelGeneratortargetPackagecom.demo.entitytargetProjectsrc/main/java/javaClientGeneratortargetPackagecom.demo.mappertargetProjectsrc/main/javatypeXMLMAPPER/tabletableNameuser//context/generatorConfiguration整合 PageHelper 分页插件PageHelper 是常用的物理分页插件一行代码即可实现分页PageHelper.startPage(1,10);ListUserusersuserMapper.selectAll();PageInfoUserpageInfonewPageInfo(users);dependencygroupIdcom.github.pagehelper/groupIdartifactIdpagehelper-spring-boot-starter/artifactIdversion1.4.7/version/dependency四、总结本文系统梳理了 MyBatis 的高级核心特性与生态整合方案动态 SQL掌握if、choose、where、set、foreach、sql/include等标签灵活应对复杂查询与批量操作复杂关联映射区分association与collection优先使用嵌套结果规避 N1 问题缓存机制理解一级缓存与二级缓存的作用域、失效场景与生产避坑点生态整合掌握 Spring 原生整合与 SpringBoot 3.x 自动整合两种方式工程化提效善用 MyBatisX、Generator 逆向工程与 PageHelper 分页插件。掌握这些能力你就能在企业级项目中高效、稳健地使用 MyBatis 完成复杂业务开发。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

CTP高频交易系统实战:从Tick到报单的模块拆解与避坑指南 2026/10/2 15:17:21

CTP高频交易系统实战:从Tick到报单的模块拆解与避坑指南

简介:这份PDF文献面向金融工程、量化交易与高频系统开发方向的学习者和研究人员,围绕密集实时数据处理场景,讲解交互式高频交易系统的设计思路与实现路径,适合作为课程设计、课题研究或技术选型阶段的参考文献。压缩包内仅含1个PD…

阅读更多 →
微信小程序分享功能实战:好友分享与朋友圈单页模式全解析 2026/10/2 15:17:21

微信小程序分享功能实战:好友分享与朋友圈单页模式全解析

做微信小程序,分享功能是绕不开的一环。用户能一键把内容转发给好友、晒到朋友圈,小程序的传播才能转起来。我在日常开发里被问得最多的就是这两件事:怎么让右上角出现“分享到朋友圈”?为什么onShareAppMessage写好了&#xff0c…

阅读更多 →
【Claude Code】Invalid API key 密钥无效错误排查 + 凭证源冲突解决:把 settings 改到 TaoToken 2026/10/2 15:17:21

【Claude Code】Invalid API key 密钥无效错误排查 + 凭证源冲突解决:把 settings 改到 TaoToken

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
微信小程序分享功能全解析:好友与朋友圈的差别及实现 2026/10/2 15:17:20

微信小程序分享功能全解析:好友与朋友圈的差别及实现

做微信小程序,几乎绕不开分享这个功能。不管是拉新、社群分发,还是单纯让朋友帮忙看一眼,微信小程序里最常用的两个入口就是分享给好友和分享到朋友圈。很多开发者一开始以为这两件事差不多,都是右上角三个点然后选分享&#xff0…

阅读更多 →
Python调用FFmpeg报错Unknown encoder: libx264的排查与解决 2026/10/2 15:17:20

Python调用FFmpeg报错Unknown encoder: libx264的排查与解决

最近在写一个批量视频转码脚本时,被 FFmpeg 的报错折腾了一下午。脚本在本地跑得好好的,一放到服务器上就崩,日志里留下了这么一段: subprocess.CalledProcessError: Command [ffmpeg, -i, input.mp4, -c:v, libx264, output.mp…

阅读更多 →
左手坐标系与右手坐标系详解:三维开发中的坐标转换与实战排查 2026/10/2 15:17:01

左手坐标系与右手坐标系详解:三维开发中的坐标转换与实战排查

1. 空间直角坐标系:三维世界的"定位系统" 1.1 从一维到三维:为什么必须要有坐标系 我们在中学就接触过数轴,一条直线上定好原点、正方向和单位长度,任何一个实数就能对应到直线上唯一的一个点,这就是一维世…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉