MyBatis 知识点总结
一、MyBatis 简介MyBatis是一款优秀的持久层框架它支持自定义 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的工作可以使用简单的 XML 或注解来配置和映射原生信息将接口和 Java 的 POJOsPlain Old Java Objects普通的 Java 对象映射成数据库中的记录。二、核心组件与工作原理1. 核心组件SqlSessionFactoryBuilder用于创建 SqlSessionFactory 实例。SqlSessionFactory每个 MyBatis 应用的核心用于创建 SqlSession 实例。SqlSession包含了执行 SQL 命令所需的所有方法是 MyBatis 与数据库交互的会话。ExecutorMyBatis 执行器负责 SQL 语句的生成和查询缓存的维护。MappedStatement封装了 SQL 语句的映射信息。ParameterHandler负责将用户传递的参数转换成 JDBC Statement 所需的参数。ResultSetHandler负责将 JDBC 返回的 ResultSet 结果集对象转换成 List 集合。2. 工作原理读取 MyBatis 配置文件mybatis-config.xml和映射文件Mapper.xml。通过 SqlSessionFactoryBuilder 构建 SqlSessionFactory。SqlSessionFactory 创建 SqlSession。SqlSession 调用 Executor 执行器执行映射文件中定义的 SQL。Executor 通过 MappedStatement 对象获取 SQL 信息通过 ParameterHandler 设置参数通过 ResultSetHandler 处理结果集。返回处理结果。三、配置文件详解1. 核心配置文件mybatis-config.xml?xml version1.0 encodingUTF-8? !DOCTYPE configuration PUBLIC -//mybatis.org//DTD Config 3.0//EN http://mybatis.org/dtd/mybatis-3-config.dtd configuration !-- 环境配置 -- environments defaultdevelopment environment iddevelopment transactionManager typeJDBC/ dataSource typePOOLED property namedriver valuecom.mysql.cj.jdbc.Driver/ property nameurl valuejdbc:mysql://localhost:3306/mybatis_db/ property nameusername valueroot/ property namepassword value123456/ /dataSource /environment /environments !-- 映射器配置 -- mappers mapper resourcecom/example/mapper/UserMapper.xml/ /mappers /configuration2. 映射文件Mapper.xml?xml version1.0 encodingUTF-8? !DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd mapper namespacecom.example.mapper.UserMapper !-- 结果映射 -- resultMap iduserResultMap typecom.example.entity.User id propertyid columnid/ result propertyusername columnusername/ result propertyemail columnemail/ /resultMap !-- 查询语句 -- select idselectUserById resultMapuserResultMap SELECT * FROM user WHERE id #{id} /select /mapper四、动态 SQLMyBatis 的动态 SQL 功能是其核心特性之一它允许在 XML 映射文件中编写灵活的 SQL 语句根据传入参数的条件动态地拼接 SQL 片段从而避免了在 Java 代码中拼接字符串的繁琐和潜在的安全风险。1. 动态 SQL 标签if 标签作用根据条件判断是否包含 SQL 片段。属性test属性用于指定 OGNL 表达式表达式结果为 true 时标签内的 SQL 会被包含。select idfindActiveUser resultTypeUser SELECT * FROM user WHERE status ACTIVE if testusername ! null and username ! AND username #{username} /if if testemail ! null AND email #{email} /if /selectchoose, when, otherwise 标签作用实现多分支条件选择类似于 Java 中的switch-case-default语句。select idfindUserByState resultTypeUser SELECT * FROM user WHERE choose when teststate ACTIVE status ACTIVE /when when teststate INACTIVE status INACTIVE /when otherwise status IS NOT NULL /otherwise /choose /selecttrim, where, set 标签where智能处理 WHERE 子句。只有当其包含的标签有返回值时才会插入 “WHERE” 关键字。如果标签返回的内容以 “AND” 或 “OR” 开头它会自动将其去除。!-- 使用 where 标签避免 WHERE 后直接跟 AND 导致语法错误 -- select idfindUsers resultTypeUser SELECT * FROM user where if testusername ! null AND username #{username} /if if testemail ! null AND email #{email} /if /where /selectset智能处理 UPDATE 语句中的 SET 子句。它会动态地在行首添加 SET 关键字并会删掉无关的逗号。update idupdateUser UPDATE user set if testusername ! nullusername #{username},/if if testemail ! nullemail #{email},/if if teststatus ! nullstatus #{status},/if /set WHERE id #{id} /updatetrim功能更强大的标签可以自定义前缀、后缀以及要删除的前缀/后缀字符串。可用于替代where或set。!-- 用 trim 实现 where 标签的功能 -- select idfindUsers resultTypeUser SELECT * FROM user trim prefixWHERE prefixOverridesAND |OR if testusername ! null AND username #{username} /if if testemail ! null AND email #{email} /if /trim /selectforeach 标签作用遍历集合如 List、Set、数组、Map常用于构建 IN 条件或批量操作。属性collection指定要遍历的集合属性名。item遍历过程中每个元素的别名。index遍历 List 或数组时的索引遍历 Map 时的 key。open遍历开始时添加的字符串。close遍历结束时添加的字符串。separator元素之间的分隔符。!-- 构建 IN 查询 -- select idselectUsersInIds resultTypeUser SELECT * FROM user WHERE id IN foreach collectionids itemid open( separator, close) #{id} /foreach /select !-- 批量插入 -- insert idbatchInsertUsers INSERT INTO user (username, email) VALUES foreach collectionuserList itemuser separator, (#{user.username}, #{user.email}) /foreach /insertbind 标签作用创建一个变量通常用于模糊查询或字符串处理并将其绑定到上下文可以在 OGNL 表达式中使用。select idfindUsersLikeName resultTypeUser bind namepattern value% username % / SELECT * FROM user WHERE username LIKE #{pattern} /select2. 动态 SQL 原理与最佳实践原理MyBatis 在解析 XML 映射文件时会构建一个包含动态 SQL 节点如if,foreach的 SQL 源对象。执行时根据传入的参数对象使用 OGNL 表达式计算每个动态节点的test条件动态地拼接出最终的 SQL 字符串。最佳实践优先使用where和set标签避免 SQL 语法错误。在if的test条件中使用and和or进行逻辑判断注意字符串空值判断testname ! null and name ! 。对于复杂的动态 SQL可以考虑使用sql标签定义可重用的 SQL 片段再用include标签引用提高可维护性。注意性能过于复杂的动态 SQL 可能会影响 SQL 解析和缓存效率。对于固定模式的多条件查询可以考虑使用 MyBatis-Plus 等增强框架的 QueryWrapper。3. 综合示例select idselectByCondition resultTypeUser SELECT * FROM user where if testusername ! null and username ! bind nameusernamePattern value% username % / AND username LIKE #{usernamePattern} /if if teststatusList ! null and statusList.size() 0 AND status IN foreach collectionstatusList itemstatus open( separator, close) #{status} /foreach /if choose when testorderBy name ORDER BY username /when when testorderBy time ORDER BY create_time DESC /when otherwise ORDER BY id /otherwise /choose /where /select五、高级特性1. 一级缓存与二级缓存一级缓存SqlSession 级别默认开启同一个 SqlSession 中执行相同的 SQL 查询第二次会从缓存中获取。二级缓存Mapper 级别需要手动开启多个 SqlSession 共享缓存数据。2. 延迟加载懒加载与立即加载延迟加载Lazy Loading也称为懒加载是指在需要时才加载关联数据。MyBatis 默认使用立即加载但可以通过配置开启延迟加载。立即加载Eager Loading在查询主对象时同时加载所有关联对象的数据。配置延迟加载!-- 在 mybatis-config.xml 中配置 -- settings !-- 开启延迟加载 -- setting namelazyLoadingEnabled valuetrue/ !-- 开启按需加载3.4.1版本默认true -- setting nameaggressiveLazyLoading valuefalse/ /settings映射文件中的配置!-- 在 resultMap 中配置关联关系的加载方式 -- resultMap idblogResultMap typeBlog id propertyid columnid/ result propertytitle columntitle/ !-- 立即加载 -- association propertyauthor columnauthor_id javaTypeAuthor selectselectAuthorById/ !-- 延迟加载 -- collection propertycomments columnid ofTypeComment selectselectCommentsByBlogId fetchTypelazy/ /resultMap立即加载 vs 延迟加载的选择立即加载适用场景关联数据量小且大概率会被使用需要一次性获取完整对象图N1 查询问题不严重的情况延迟加载适用场景关联数据量大可能不会被使用需要优化首次查询性能避免不必要的数据库查询关联对象层级较深的情况延迟加载的实现原理MyBatis 通过动态代理技术CGLIB 或 Javassist创建关联对象的代理。当访问代理对象的属性或方法时才会触发真正的 SQL 查询。3. 插件InterceptorMyBatis 允许在映射语句执行过程中的某些点进行拦截调用可以用于分页、性能监控、SQL 日志等场景。六、常见面试题#{} 和 ${} 的区别是什么#{}预编译处理可以防止 SQL 注入。${}字符串替换直接拼接 SQL 语句存在 SQL 注入风险。MyBatis 如何实现延迟加载通过配置setting namelazyLoadingEnabled valuetrue/开启使用 CGLIB 或 Javassist 创建代理对象在真正访问关联对象时才执行查询。MyBatis 有哪些执行器SimpleExecutor每执行一次 update 或 select就开启一个 Statement 对象用完立刻关闭。ReuseExecutor执行 update 或 select以 SQL 作为 key 查找 Statement 对象存在就使用不存在就创建。BatchExecutor执行 update没有 selectJDBC 批处理不支持 select将所有 SQL 都添加到批处理中等待统一执行。

相关新闻

Java泛型接口详解

Java泛型接口详解

1. 泛型接口概述泛型接口是Java泛型编程的重要组成部分&#xff0c;它允许在接口定义中使用类型参数&#xff0c;从而创建更灵活、类型安全的API。2. 泛型接口的基本语法泛型接口的声明使用尖括号<>来指定类型参数&#xff0c;这些参数可以在接口的方法签名和返回类型中使…

2026/10/20 7:41:36 阅读更多 →
Project计划高效导出Excel:3种方法详解与避坑指南

Project计划高效导出Excel:3种方法详解与避坑指南

1. 从甘特图到数据表&#xff1a;为什么需要将Project计划导出为Excel 在日常的项目管理工作中&#xff0c;我们常常会遇到一个非常具体的需求&#xff1a;如何把在Microsoft Project里精心排布好的项目计划&#xff0c;完整地“搬”到Excel里。这听起来像是一个简单的“另存为…

2026/10/19 13:41:12 阅读更多 →
网站建设应注重实用性:拒绝花哨陷阱,回归商业本质才是硬道理

网站建设应注重实用性:拒绝花哨陷阱,回归商业本质才是硬道理

在这个互联网信息爆炸的时代,如果你去问十个老板或者创业者:“你们公司网站是做什么的?”得到的回答千奇百怪。有的说是品牌展示窗口,有的说是获客渠道,还有的说是为了“跟上时代步伐”。但是,当你真正去审视那些号称价值连城、耗资百万打造的“国际范儿”网站时,你会发…

2026/10/17 4:58:56 阅读更多 →

最新新闻

Postgres-XL GTM节点部署管理与高可用运维实战

Postgres-XL GTM节点部署管理与高可用运维实战

接手任何一套Postgres-XL集群&#xff0c;我第一件事永远是去查GTM那层&#xff0c;而不是先看Coordinator和Datanode。很多人觉得GTM就是个发号器&#xff0c;配置文件里填个IP就行&#xff0c;直到线上出现交易卡死、事务号断层、快照错乱&#xff0c;才回头承认这玩意儿才是…

2026/10/20 7:41:10 阅读更多 →
iOS TableView图片异步加载:解码、缓存与复用三重优化

iOS TableView图片异步加载:解码、缓存与复用三重优化

简介&#xff1a;本资源是一份面向iOS初中级开发者的UITableView图片异步加载实战项目&#xff0c;聚焦解决列表滚动卡顿这一高频性能问题&#xff0c;适用于新闻流、商品列表等需大量网络图片展示的典型场景。压缩包为73KB的ZIP文件&#xff0c;共含33个文件&#xff0c;涵盖7…

2026/10/20 7:41:10 阅读更多 →
论文降重全攻略:查重原理、工具流派与实操避坑指南

论文降重全攻略:查重原理、工具流派与实操避坑指南

又是一年毕业季&#xff0c;后台涌进来不少2026届的同学&#xff0c;问得最多的一个问题就是&#xff1a;查重报告飘红一片&#xff0c;降重复率降到怀疑人生&#xff0c;到底有没有靠谱的"神器"能救命。这个问题我太熟了&#xff0c;前几年帮实验室的学弟学妹改论文…

2026/10/20 7:41:10 阅读更多 →
Qt工控上位机开发:选型、架构与现场部署实战

Qt工控上位机开发:选型、架构与现场部署实战

做工业控制和嵌入式设备软件这些年&#xff0c;我越来越觉得Qt是个被低估的选择。很多人一听到Qt就觉得是“老古董界面框架”&#xff0c;但其实真正到了设备现场&#xff0c;面对恶劣的通信环境、不确定的硬件兼容性、动不动就要改需求的客户&#xff0c;Qt反而是最让人心里有…

2026/10/20 7:41:10 阅读更多 →
遗传算法优化XGBoost参数,破解时间序列预测过拟合难题

遗传算法优化XGBoost参数,破解时间序列预测过拟合难题

接手过一个实际的时间序列预测项目的人&#xff0c;基本都经历过这个场景&#xff1a;模型在训练集上表现近乎完美&#xff0c;R到了0.98&#xff0c;验证集也有0.89&#xff0c;看着一切正常&#xff0c;可一旦让它去预测未来一个月的数据&#xff0c;误差立刻放飞自我。我第一…

2026/10/20 7:41:10 阅读更多 →
工业相机采集卡C#开发实战:CG300 Demo工程解析与二次开发

工业相机采集卡C#开发实战:CG300 Demo工程解析与二次开发

简介&#xff1a;这份资源是大恒CG300采集卡的C#示例工程&#xff0c;面向从事工业控制、图像处理与科学研究的C#开发者&#xff0c;尤其是需要基于该卡做二次开发、多通道数据采集与实时显示的技术人员。压缩包共28个文件&#xff0c;约78KB&#xff0c;以cs源码、exe可执行程…

2026/10/20 7:40:10 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

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

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

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

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

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

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/19 10:02:04 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/19 17:32:41 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

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

2026/10/19 2:54:50 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

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

2026/10/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

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

2026/10/18 12:16:16 阅读更多 →