一、MyBatis的Executor执行器详解

1. MyBatis执行器类型

MyBatis有三种核心执行器实现,在org.apache.ibatis.executor包中定义:

执行器类型特点描述
SimpleExecutor默认执行器,每次执行都会创建新的Statement对象
ReuseExecutor重用预处理语句(PreparedStatement),减少重复编译
BatchExecutor批量操作执行器,将多个更新操作合并批处理
CachingExecutor装饰器模式实现,为其他执行器提供二级缓存功能

2. 各执行器实现原理与区别

2.1 SimpleExecutor
  • 工作原理

    • 每次执行update或query都会创建新的PreparedStatement

    • 执行完毕后立即关闭Statement

  • 优点:实现简单,无状态,线程安全

  • 缺点:频繁创建/关闭Statement,性能开销较大

  • 适用场景:常规单条SQL操作

2.2 ReuseExecutor
  • 工作原理

    • 维护一个Statement缓存Map(key为SQL语句)

    • 相同SQL重复使用已创建的PreparedStatement

  • 优点:减少SQL预编译开销,提升重复SQL执行效率

  • 缺点:需要维护Statement缓存,长时间不用的Statement不会主动关闭

  • 适用场景:短时间内重复执行相同SQL语句

2.3 BatchExecutor
  • 工作原理

    • 将多个update操作缓存起来

    • 等待显式调用flushStatements()时批量提交

    • 使用JDBC的addBatch()/executeBatch()机制

  • 优点:大幅提升批量操作性能(减少网络往返)

  • 缺点:需要手动控制批量提交时机

  • 适用场景:批量插入、更新、删除操作

2.4 CachingExecutor
  • 特殊性质

    • 装饰器模式实现,不单独使用

    • 为其他执行器添加二级缓存功能

    • 通过TransactionalCacheManager管理缓存事务

  • 工作流程

    1. 先查询二级缓存

    2. 缓存未命中时委托给被装饰的执行器执行

    3. 将结果存入缓存

3. 执行器配置与选择

配置方式(mybatis-config.xml):

xml

<settings><!-- 可选值:SIMPLE(默认), REUSE, BATCH --><setting name="defaultExecutorType" value="REUSE"/>
</settings>
代码中临时切换:

java

SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
try {UserMapper mapper = session.getMapper(UserMapper.class);// 批量操作...session.commit();
} finally {session.close();
}

4. 执行器选择建议

  1. 常规CRUD:使用默认的SimpleExecutor即可

  2. 高频重复SQL:考虑使用ReuseExecutor

  3. 批量数据处理:显式使用BatchExecutor

  4. 缓存需求:配合CachingExecutor使用

二、MyBatis半自动ORM特性解析

1. ORM工具分类标准

特性全自动ORM半自动ORM
SQL生成框架自动生成开发者编写
对象-关系映射自动映射显式配置
学习曲线较陡峭较平缓
灵活性较低较高
性能控制较难优化易于优化
典型代表Hibernate, JPAMyBatis

2. MyBatis作为半自动ORM的核心表现

  1. SQL控制权

    • 开发者需要手动编写和维护SQL语句

    • 可以精确控制每个查询的细节

    • 支持原生SQL和动态SQL

  2. 映射配置

    • 需要显式定义ResultMap/ResultType

    • 关联关系需要手动配置(嵌套查询/嵌套结果)

    • 支持高级映射(构造函数映射、鉴别器等)

  3. 会话管理

    • 需要手动管理SqlSession生命周期

    • 显式控制事务边界

  4. 延迟加载

    • 需要手动配置fetchType="lazy"

    • 理解SqlSession作用域对延迟加载的影响

3. 半自动与全自动ORM的典型区别

查询示例对比:

JPA (全自动)

java

// 自动生成SQL:SELECT * FROM users WHERE name = ?
List<User> users = entityManager.createQuery("SELECT u FROM User u WHERE u.name = :name", User.class).setParameter("name", "张三").getResultList();

MyBatis (半自动)

xml

<!-- 需手动编写SQL -->
<select id="findByName" resultType="User">SELECT * FROM users WHERE name = #{name}
</select>

java

// 执行明确映射的SQL
List<User> users = sqlSession.selectList("findByName", "张三");

4. 半自动设计的优势与代价

优势

  1. 性能可控:可优化每一句SQL

  2. 灵活性强:支持复杂查询和存储过程

  3. 过渡平滑:适合从原生JDBC迁移

  4. 技术债务少:避免全自动ORM的"魔法"行为

代价

  1. 开发效率:需要编写更多样板代码

  2. 维护成本:SQL分散在XML/注解中

  3. 移植性:数据库方言差异需要手动处理

三、MyBatis核心理解与架构剖析

1. MyBatis架构全景图

text

[应用程序]|v
[MyBatis API] (SqlSession, MapperProxy)|v
[核心执行流程] |-- 配置解析|-- SQL解析|-- 参数处理|-- SQL执行|-- 结果映射|v
[JDBC]

2. 核心组件与工作流程

  1. 配置阶段

    • 解析mybatis-config.xml全局配置

    • 加载Mapper.xml映射文件

    • 构建Configuration对象(包含所有配置信息)

  2. 会话阶段

    • 创建SqlSessionFactory

    • 开启SqlSession(包含Executor实例)

    • 获取Mapper接口代理对象(MapperProxy)

  3. 执行阶段

    • 参数处理(TypeHandler)

    • SQL解析(包括动态SQL)

    • 执行查询/更新(通过Executor)

    • 结果映射(ResultSetHandler)

  4. 缓存体系

    • 一级缓存(SqlSession级别)

    • 二级缓存(Mapper级别)

3. MyBatis的核心价值主张

  1. SQL与代码分离

    • SQL保存在XML/注解中

    • 业务代码不掺杂SQL字符串拼接

  2. 简化JDBC但不隐藏

    • 封装了样板代码(连接管理、结果集遍历等)

    • 仍保持对JDBC底层访问的能力

  3. 灵活的结果映射

    • 支持简单POJO到复杂嵌套对象

    • 可自定义TypeHandler处理特殊类型

  4. 插件扩展体系

    • 可拦截四大核心组件

    • 实现分页、审计等通用功能

4. 适用场景分析

最适合场景

  • 需要高度优化SQL性能的项目

  • 遗留数据库或复杂数据库模式

  • 需要调用存储过程的系统

  • 对SQL有深度控制需求的团队

不太适合场景

  • 快速原型开发

  • 简单CRUD为主的应用程序

  • 需要跨数据库移植的项目

5. MyBatis的演进趋势

  1. 注解支持增强

    • @Select, @Insert等注解功能不断完善

    • 动态SQL也可以通过@SelectProvider实现

  2. Spring Boot整合

    • MyBatis-Spring-Boot-Starter简化配置

    • 自动发现Mapper接口

  3. Kotlin支持

    • 更好的Kotlin DSL支持

    • 协程等现代特性整合

  4. 响应式编程

    • 实验性的响应式MyBatis实现

    • 集成R2DBC等响应式驱动

四、总结对比表格

执行器对比

执行器类型线程安全Statement重用批量支持缓存支持适用场景
SimpleExecutor需装饰常规操作
ReuseExecutor是(SQL级别)需装饰重复SQL高频执行
BatchExecutor需装饰批量插入/更新
CachingExecutor依赖被装饰者依赖被装饰者需要二级缓存的场景

ORM类型对比

特性维度全自动ORMMyBatis(半自动)
学习成本较高中等
开发效率高(简单CRUD)中(需写SQL)
性能优化较难容易
复杂查询支持有限强大
数据库移植性需手动调整
社区生态丰富(JPA)非常丰富

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

红黑树的特性与实现

在数据结构领域&#xff0c;二叉搜索树&#xff08;BST&#xff09;凭借 O (log n) 的平均时间复杂度成为查找、插入和删除操作的优选结构。但它有个致命缺陷&#xff1a;当输入数据有序时&#xff0c;会退化为链表&#xff0c;时间复杂度骤降至 O (n)。为解决这一问题&#xf…

ClickHouse从入门到企业级实战全解析课程简介

【课程简介】你是否正在面临这些挑战&#xff1f;海量数据的分析查询慢如蜗牛&#xff0c;报表一等就是几小时&#xff1f;想构建实时数仓&#xff0c;却不知如何高效处理 Kafka 等流式数据&#xff1f;对 ClickHouse 的众多 MergeTree 引擎感到困惑&#xff0c;不知如何选型&a…

【新启航】从人工偏差到机械精度:旋转治具让三维扫描重构数据重复精度提升至 ±0.01mm

在三维扫描重构领域&#xff0c;传统人工操作方式受限于人为因素干扰&#xff0c;数据重复精度难以保证&#xff0c;无法满足高精度工业检测与逆向工程需求。旋转治具凭借先进的机械设计与自动化控制技术&#xff0c;将三维扫描重构数据重复精度提升至 0.01mm&#xff0c;实现从…

《汇编语言:基于X86处理器》第13章 复习题和编程练习

本篇记录了《汇编语言&#xff1a;基于X86处理器》第13章 复习题和编程练习的学习笔记。13.6 复习题1.当汇编过程被高级语言程序调用时&#xff0c;主调程序与被调过程是否应使用相同的内存模式?答&#xff1a;主调程序与被调过程使用的内存模式必须相同。2.C 和 C程序调用汇编…

SpringAI智能航空助手实战<Demo>

我们将如何将我们得传统业务进行智能化的改造>>>1.将我们传统的航空票务系统 我们之前通过按钮的方式来完成 现在我们通过智能对话的方式完成 >现在我们通过对话的方式来完成 整个智能化的改造 传统应用如何进行智能化改造 我们把我们的项目通过Spring-ai 来接入A…

windows git安装步骤

1&#xff0c;从官网下载安装包&#xff1a;gitg官网 进行安装 2&#xff0c;配置git环境&#xff1a; git config --global user.name "Your Name" git config --global user.email "Your Email"3&#xff0c;生成 SSH Key&#xff1a; ssh-keygen -t r…

使用chroma和LlamaIndex做RAG增强

RAG 原理&#xff1a;通过 “检索&#xff08;从知识库获取相关信息&#xff09;→ 增强&#xff08;将信息作为上下文输入模型&#xff09;→ 生成&#xff08;模型基于上下文回答&#xff09;” 三步&#xff0c;解决大模型知识时效性、领域局限性问题。 接下来将完成这么一个…

2025 最应避免的摄影陷阱以及解决方案

你有没有想过&#xff0c;当你拍完了一个完美的场景后&#xff0c;却发现画面模糊、光线不足&#xff0c;或者更糟的是&#xff0c;存储卡中的文件丢失了&#xff1f;这些问题可能会发生在任何人身上&#xff0c;无论是业余爱好者、专业人士还是最好的摄影师。当珍贵的记忆变成…

python类--python011

面向对象编程中的类的概念、属性使用、继承和类的改造问题等。7.1 初识类在软件编程中&#xff0c;面向过程和面向对象是两种主要的编程方法。面向过程的编程强调通过函数来实现特定的功能&#xff0c;具有灵活性&#xff0c;但在复杂系统中往往导致代码重复&#xff0c;维护困…

Python函数篇:从零到精通

一、函数1.1 为什么有函数我们对于一个项目时&#xff0c;会有上千甚至上万条代码&#xff0c;当我们要使用到某个函数时&#xff0c;例如我需要计算一个求和代码&#xff0c;获得求和的值来服务我们的项目&#xff0c;那我们可能会这样#计算1&#xff5e;100的和 theSun 0 fo…

QT项目之记事本

本文用QT实现记事本功能。一、成品展示1.界面主要元素&#xff1a;1.标题为MyNoteBook&#xff1b;2.相应图标为&#xff1a;打开文件&#xff0c;保存&#xff0c;退出&#xff1b;3.右下角标注光标所在行列&#xff0c;默认编码方式为UTF-8&#xff1b;4.鼠标所在图标位置时会…

【软件测试】性能测试 —— 工具篇 JMeter 介绍与使用

&#x1f970;&#x1f970;&#x1f970;来都来了&#xff0c;不妨点个关注叭&#xff01; &#x1f449;博客主页&#xff1a;欢迎各位大佬!&#x1f448; 文章目录1. JMeter 的介绍2. JMeter 安装、配置、搭建2.1 前置条件 —— Java环境搭建2.2 JMeter 下载2.3 JMeter 安装…

二十二、Mybatis-快速入门程序

入门程序大概步骤叙述&#xff1a; 步骤一&#xff1a;创建springboot工程并且数据库提前创建表步骤二&#xff1a;创建springboot工程对Mybatis相关依赖注意打勾步骤三&#xff1a;编写查找方法步骤四&#xff1a;编写测试方法项目目录结构与数据库以及代码&#xff1a; 项目目…

Blender模拟结构光3D Scanner(一)外参数匹配

如何使用Blender模拟FPP(Fringe Projection Profilometry) 原理的结构光3D传感器&#xff1f;主要包含的工作有&#xff1a;1&#xff09;相机、投影仪定位与内外参数匹配&#xff1b;2&#xff09;投影仪投射指定Pattern图像&#xff1b;3&#xff09;被测物体材质属性配置等&…

LangChain是如何实现RAG多轮问答的

目录引言一、LangChain实现RAG多轮问答核心机制1. 对话历史管理&#xff08;Memory&#xff09;2. 问题重写&#xff08;Query Rewriting&#xff09;3. 检索增强生成&#xff08;RAG Core&#xff09;4. 链式工作流&#xff08;Chain&#xff09;二、关键设计特点三、完整示例…

DAY 44 预训练模型

知识点回顾&#xff1a; 预训练的概念常见的分类预训练模型图像预训练模型的发展史预训练的策略预训练代码实战&#xff1a;resnet18 一、预训练的概念 我们之前在训练中发现&#xff0c;准确率最开始随着epoch的增加而增加。随着循环的更新&#xff0c;参数在不断发生更新。 所…

Java Stream API 中常用方法复习及项目实战示例

在最近的练手项目中&#xff0c;对于stream流的操作愈加频繁&#xff0c;我也越来越感觉stream流在处理数据是的干净利落&#xff0c;因此写博客用来记录最近常用的方法以便于未来的复习。map() 方法map()是一个中间操作&#xff08;intermediate operation&#xff09;&#x…

从零开始手搓一个GPT大语言模型:从理论到实践的完整指南(一)

现在人工智能飞速发展时代&#xff0c;LLM绝对可以算是人工智能领域得一颗明珠&#xff0c;也是现在许多AI项目落地得必不可少得一个模块&#xff0c;可以说&#xff0c;不管你之前得研究领域是AI得哪个方向&#xff0c;现在都需要会一些LLM基础&#xff0c;在这个系列&#xf…

Redis ubuntu下载Redis的C++客户端

1. 安装 redis-plus-plus C 操作 Redis 的库有很多&#xff0c;这里选择使用 redis-plus-plus&#xff0c;这个库的功能强大&#xff0c;使用简单。 Github 地址&#xff1a;GitHub - sewenew/redis-plus-plus: Redis client written in C 访问不了Github 地址的可以使用Ste…

nm命令和nm -D命令参数

出现这种差异的原因在于&#xff1a;动态库中的符号分为两种类型&#xff1a; 常规符号表&#xff08;regular symbol table&#xff09;&#xff1a;通常用于静态链接和调试&#xff0c;默认不包含在动态库中&#xff08;除非显式保留&#xff09;。动态符号表&#xff08;dyn…