当前位置: 首页 > news >正文

mybatis vs mybatis-plus

 

   

​核心关系:​​ MyBatis-Plus ​​不是​​ MyBatis 的替代品,而是构建在 MyBatis ​​之上​​的一个强大的​​增强工具包​​。它完全兼容原生 MyBatis,并在其基础上提供了大量开箱即用的功能,极大地简化了开发,尤其是单表操作。


​一、 MyBatis 核心原理​

MyBatis 的核心思想是将 ​​SQL 语句从 Java 代码中解耦​​,通过配置或注解来管理 SQL,并提供灵活的 ORM 映射。其核心原理围绕以下几个关键组件和流程:

  1. SqlSessionFactoryBuilder & SqlSessionFactory:​

    • ​作用:​​ 应用启动时,读取 MyBatis 的全局配置文件 (mybatis-config.xml) 和所有的 Mapper XML 文件(或注解配置)。
    • ​原理:​SqlSessionFactoryBuilder 解析这些配置文件,构建出包含所有配置信息(数据源、事务管理器、类型处理器、插件、Mapper 注册信息等)的 Configuration 对象,并最终创建出 SqlSessionFactorySqlSessionFactory 是生产 SqlSession 的工厂。
  2. SqlSession:​

    • ​作用:​​ 代表一次与数据库的会话。它是 MyBatis 工作的​​核心入口​​。
    • ​原理:​​ 通过 SqlSessionFactory.openSession() 获取。它提供了执行 SQL 命令(selectOne, selectList, insert, update, delete)、获取 Mapper 接口代理对象、管理事务等方法。每个 SqlSession 通常对应一个数据库连接(或连接池中的一个连接)。
  3. Executor:​

    • ​作用:​SqlSession 内部真正​​执行 SQL 操作​​的组件。
    • ​原理:​SqlSession 将请求委托给 ExecutorExecutor 负责维护一级缓存(SqlSession 级别)、处理延迟加载、调用 StatementHandler 等。常见的实现有 SimpleExecutor(每次执行创建新 Statement)、ReuseExecutor(重用 Statement)、BatchExecutor(批处理)。
  4. StatementHandler:​

    • ​作用:​​ 负责​​创建 JDBC Statement 对象​​(PreparedStatement, CallableStatement, Statement),并​​设置参数​​、​​执行 SQL​​。
    • ​原理:​Executor 调用 StatementHandler。它使用 ParameterHandler 将 Java 对象参数设置到 SQL 的占位符 (?) 上。
  5. ParameterHandler:​

    • ​作用:​​ 负责将​​用户传入的 Java 参数​​,按照 SQL 语句中的占位符 (?) 进行​​类型转换和设置​​。
    • ​原理:​​ 利用注册的 TypeHandler 完成 Java 类型到 JDBC 类型的转换。
  6. TypeHandler:​

    • ​作用:​​ 负责 ​​Java 类型和 JDBC 类型之间的相互转换​​。
    • ​原理:​​ MyBatis 内置了常用类型(如 String, Integer, Date 等)的处理器。用户可以自定义处理器处理特殊类型(如枚举)。
  7. ResultSetHandler:​

    • ​作用:​​ 负责将 JDBC ResultSet 返回的结果集​​转换​​为​​指定的 Java 对象​​(单个对象、List、Map 等)。
    • ​原理:​​ 根据 Mapper 方法定义的返回类型(或 resultMap 配置),利用 TypeHandler 和反射,将结果集的每一行数据映射成 Java 对象。
  8. MappedStatement:​

    • ​作用:​​ 代表一个映射的 SQL 语句。它是 MyBatis 配置的核心单元。
    • ​原理:​​ 存储了 SQL 语句本身(<select>, <insert> 等标签的内容)、参数映射信息 (<parameterMap>@Param)、结果映射信息 (<resultMap>@Result)、SQL 命令类型(SELECT/INSERT 等)、缓存配置等。一个 Mapper 接口方法对应一个 MappedStatement
  9. ​配置方式:​

    • ​XML 配置:​​ 主要方式。通过 mybatis-config.xml 配置全局设置,通过 Mapper.xml 文件定义 SQL 和映射关系。
    • ​注解配置:​​ 在 Mapper 接口方法上使用 @Select, @Insert, @Update, @Delete, @Results 等注解直接编写 SQL 和映射规则。通常用于简单 SQL。

​MyBatis 工作流程总结:​

  1. 应用启动:解析配置 -> 构建 Configuration -> 创建 SqlSessionFactory
  2. 业务请求:SqlSessionFactory -> 创建 SqlSession
  3. 执行操作:
    • 通过 SqlSession 直接执行 SQL 方法 (selectOne, update 等)。
    • 或通过 SqlSession.getMapper() 获取 Mapper 接口的​​动态代理对象​​。
  4. 代理对象调用:代理对象根据方法名找到对应的 MappedStatement
  5. Executor 执行:Executor 根据 MappedStatement 信息,调用 StatementHandler 创建 Statement
  6. ParameterHandler 设置参数。
  7. StatementHandler 执行 SQL。
  8. ResultSetHandler 处理结果集,映射为 Java 对象。
  9. 返回结果。

​优点:​​ 灵活、SQL 可控性强、与 JDBC 解耦、支持复杂映射、插件扩展性强。
​缺点:​​ 需要编写大量 SQL 和 XML/注解(尤其是简单 CRUD)、配置繁琐。


​二、 MyBatis-Plus (MP) 核心原理​

MP 的核心原理是在 ​​MyBatis 原有架构和机制的基础上​​,通过一系列封装、扩展和自动化技术,​​极大地简化单表操作和常用功能开发​​。它没有改变 MyBatis 的核心流程,而是增强了它。

  1. ​核心增强点:BaseMapperSqlInjector / AbstractMethod

    • ​原理:​​ MP 的核心创新。用户 Mapper 接口只需继承 BaseMapper。在应用启动时,MP 的 SqlInjector (如 DefaultSqlInjector) 会扫描这些 Mapper。
    • ​动态 SQL 生成:​​ 对于 BaseMapper 中的每个方法(insert, selectById, update 等),MP 都有一个对应的 AbstractMethod 子类(如 Insert, SelectById, Update)。这些子类在启动时,利用实体类的元数据 (TableInfo,由 @TableName, @TableId 等注解解析而来) 和预定义的 SQL 模板 (SqlMethod),​​动态生成​​该方法的完整 SQL 语句和 MappedStatement 对象,并注册到 MyBatis 的 Configuration 中。
    • ​结果:​​ 开发者无需为这些通用方法编写任何 SQL 或 XML,MP 自动提供实现。
  2. ​强大的条件构造器 (Wrapper)​

    • ​原理:​​ 提供 QueryWrapper, UpdateWrapper, LambdaQueryWrapper 等。用户通过链式调用构建复杂的查询/更新条件(eq, like, between, set 等)。
    • ​SQL 拼接:​Wrapper 内部将条件表达式存储为结构化的数据。当 Wrapper 被用于查询或更新方法时,MP 的 SQL 生成引擎会安全地(防止 SQL 注入)将这些条件​​解析并拼接到自动生成的基础 SQL 的 WHERE 子句或 SET 部分​​。
  3. ​自动配置与 Starter (Spring Boot)​

    • ​原理:​​ 提供 mybatis-plus-boot-starter。利用 Spring Boot 自动配置机制,自动创建和配置 DataSource, SqlSessionFactoryBean(注入 MP 的核心组件如 GlobalConfig, Interceptor), MapperScannerConfigurer 等,大大简化了集成步骤。
  4. ​插件体系增强​

    • ​原理:​​ 继承并扩展 MyBatis 的 Interceptor 接口,提供功能更强大、开箱即用的内置插件:
      • PaginationInnerInterceptor: 自动处理物理分页(生成 COUNT 查询和分页 SQL)。
      • OptimisticLockerInnerInterceptor: 自动实现乐观锁(基于 @Version 注解)。
      • BlockAttackInnerInterceptor: 防止全表更新/删除(安全防护)。
      • DynamicTableNameInnerInterceptor: 动态表名。
      • IllegalSQLInnerInterceptor: SQL 性能分析/阻止恶意 SQL。
    • ​工作方式:​​ 这些插件在 MyBatis 的执行流程(主要是 Executor 阶段)进行拦截,添加额外功能。
  5. ​全局配置与元数据处理​

    • GlobalConfig: 存储全局配置(表前缀、主键生成器策略、元对象处理器等)。
    • MetaObjectHandler: 实现​​自动填充​​功能(@TableField(fill = ...))。在插入或更新时,通过反射自动填充字段(如 createTime, updateTime)。
  6. ​注解驱动增强​

    • ​原理:​​ 在 MyBatis 注解基础上,提供更丰富的 ORM 和功能注解:
      • @TableName: 指定表名。
      • @TableId: 指定主键及策略(自增、UUID、雪花ID等)。
      • @TableField: 指定字段映射、自动填充策略、是否存在等。
      • @Version: 乐观锁版本字段。
      • @EnumValue: 枚举值映射。
      • @TableLogic: 逻辑删除标记。
      • @SqlParser: 过滤 SQL 解析(用于跳过某些拦截器)。
    • 这些注解信息在启动时被解析并存储在 TableInfo 等元数据对象中,供 SQL 生成、条件构造、插件等使用。

​MP 工作流程总结:​

  1. ​启动阶段:​
    • 自动配置(Spring Boot Starter)。
    • 扫描实体类注解,构建 TableInfo 等元数据。
    • 扫描 Mapper 接口(继承 BaseMapper)。
    • SqlInjectorBaseMapper 的每个方法注入对应的 AbstractMethod 实现。
    • AbstractMethod 子类利用元数据和 SQL 模板,动态生成 MappedStatement 并注册。
    • 配置并添加 MP 的内置插件到 InterceptorChain
  2. ​运行时阶段:​
    • 与原生 MyBatis 流程基本相同(SqlSession -> Executor -> ...)。
    • 当调用 BaseMapper 方法时,执行的是 MP 动态生成的 MappedStatement
    • 当使用 Wrapper 时,MP 在生成 SQL 时会解析并拼接 Wrapper 的条件。
    • MP 的插件在相应执行点进行拦截,提供分页、乐观锁等功能。

​优点:​​ 极大简化 CRUD、减少 SQL/XML 编写、内置强大功能(分页、代码生成器、乐观锁、逻辑删除等)、增强条件构造、提高开发效率。
​缺点:​​ 对复杂 SQL 和多表关联查询的支持不如直接手写 SQL/XML 灵活(虽然也能用),需要学习 MP 特有的 API 和注解。


​三、 MyBatis vs MyBatis-Plus 核心对比总结​

特性MyBatisMyBatis-Plus (MP)说明
​定位​灵活的 SQL 映射框架MyBatis 的增强工具包MP 基于 MyBatis,不是替代品。
​核心目标​SQL 与代码解耦,灵活控制 SQL​简化开发​​,尤其是单表 CRUDMP 专注于减少样板代码。
​SQL 编写​​必需​​ (XML 或注解)​可选​​ (对单表 CRUD 自动生成)MP 的 BaseMapper 自动提供通用方法实现。复杂 SQL 仍需手写。
​CRUD 实现​手动编写每个 CRUD 方法的 SQL 和映射​自动实现​BaseMapper 中的通用 CRUD 方法MP 的核心优势,省去大量简单 SQL 编写。
​条件构造​手动拼接 SQL 条件字符串 (易错,不安全)强大的 ​Wrapper API​​ (链式调用,类型安全 - LambdaWrapper,防注入)MP 提供面向对象的、安全的条件构建方式。
​分页​需手动编写分页 SQL (不同数据库语法不同)内置 ​PaginationInterceptor​ (自动物理分页)MP 的分页插件自动处理不同数据库方言、COUNT 查询和数据获取。
​主键生成​需在 SQL 或配置中处理支持多种策略 (@TableId),内置分配器 (雪花ID等)MP 简化了主键管理。
​逻辑删除​需手动在 SQL 中添加条件内置支持 (@TableLogic),自动添加过滤条件MP 自动在查询/更新中处理逻辑删除字段。
​乐观锁​需手动实现版本控制逻辑内置支持 (@Version),通过插件自动处理MP 简化了乐观锁实现。
​自动填充​需手动在代码中设置内置支持 (@TableField(fill) + MetaObjectHandler)MP 自动填充如创建时间、更新时间等字段。
​代码生成器​无官方提供,需用第三方或自研提供功能强大的 ​​代码生成器​MP 可快速生成 Entity, Mapper, Service, Controller 等基础代码。
​安全防护​无内置提供 ​BlockAttackInnerInterceptor​ 等安全插件MP 防止全表更新/删除等危险操作。
​配置复杂度​相对较高 (需配置较多 XML/注解)​显著降低​​ (尤其结合 Spring Boot Starter)MP 的自动配置和默认行为减少了大量配置。
​学习曲线​掌握 SQL/XML 映射和核心组件即可需额外学习 MP 特有的 API (Wrapper, BaseMapper), 注解和插件MP 增加了自己的抽象层。
​灵活性​​极高​​,完全掌控 SQL对单表操作灵活,对​​复杂 SQL/多表​​ 灵活性相对降低MP 处理复杂场景时,有时仍需回退到原生 MyBatis 方式 (手写 SQL/XML)。
​适用场景​需要极致 SQL 控制、复杂查询、存储过程调用快速开发、大量单表操作、需要内置功能 (分页/乐观锁等)两者并非互斥,可在同一项目中结合使用。

​总结:​

  • ​MyBatis:​​ 是​​基础​​,提供了灵活、强大的 SQL 映射能力,将开发者从 JDBC 的繁琐中解放出来,但需要编写大量 SQL 和配置。
  • ​MyBatis-Plus:​​ 是​​增强​​,在 MyBatis 的基础上,通过自动化生成、强大的条件构造器、丰富的内置功能(分页、代码生成、乐观锁等)和便捷的配置(特别是 Spring Boot),​​极大地提升了开发效率,尤其擅长处理单表操作​​。它保留了 MyBatis 的灵活性,对于复杂场景,你仍然可以像使用原生 MyBatis 一样编写自定义 SQL。

​选择建议:​

  • 如果你的项目有​​大量简单的单表 CRUD 操作​​,追求​​开发效率​​,且需要​​分页、乐观锁​​等常见功能,​​MyBatis-Plus 是绝佳选择​​。
  • 如果你的项目​​极其复杂​​,涉及大量​​定制化 SQL、存储过程、复杂的多表关联和嵌套查询​​,或者你对 SQL 有​​绝对的控制欲​​,​​原生 MyBatis 可能更合适​​(或者结合使用,复杂部分用原生)。
  • ​实际项目中,两者结合使用非常常见:​​ 简单 CRUD 用 MP 的 BaseMapperWrapper,复杂查询或存储过程调用则使用原生 MyBatis 的 XML 或注解方式编写 SQL。MP 的 @SqlParser(filter=true) 可以让你在同一个 Mapper 中混合使用这两种方式。

文章转载自:

http://goucV8hj.mqxzh.cn
http://bOsP1cmt.mqxzh.cn
http://WvA4FEFA.mqxzh.cn
http://fgKxgyKD.mqxzh.cn
http://zfKjDs2X.mqxzh.cn
http://iyiYJawi.mqxzh.cn
http://Ot0XhRTx.mqxzh.cn
http://KOX84PGZ.mqxzh.cn
http://fHtuGbMR.mqxzh.cn
http://Ww40wOa9.mqxzh.cn
http://erTOcz9s.mqxzh.cn
http://ahvD2cLQ.mqxzh.cn
http://x21Dp78g.mqxzh.cn
http://w4fwa39C.mqxzh.cn
http://JLVm2kFc.mqxzh.cn
http://PN22wL13.mqxzh.cn
http://QEgj51BL.mqxzh.cn
http://hGbfcD77.mqxzh.cn
http://byai95fY.mqxzh.cn
http://ZjETySAN.mqxzh.cn
http://93ty319m.mqxzh.cn
http://LJobYteJ.mqxzh.cn
http://gquE6bqh.mqxzh.cn
http://knR8Us8Q.mqxzh.cn
http://xEPTd4qt.mqxzh.cn
http://9i0BuR4x.mqxzh.cn
http://fJ7494Yp.mqxzh.cn
http://abq2t5xg.mqxzh.cn
http://90Z0vPjF.mqxzh.cn
http://P859TORk.mqxzh.cn
http://www.dtcms.com/a/379524.html

相关文章:

  • 网络诊断和通信中非常重要的工具或协议
  • Mysql主键选取
  • 蓝桥杯嵌入式
  • Python学习——字典和文件
  • urllib的使用
  • AFSim2.9.0学习笔记 —— 4.1、创建项目,以此项目介绍工作中Wizard使用(红方/蓝方武器平台、阵营、更换图标等,多图详细介绍)
  • 机器人驭风而行:低空经济如何开启智能新纪元【科普类】
  • 【论文速读】LLM Compiler:并行函数调用的新范式
  • 【复习】计网每日一题---海明校验码
  • CVPR 2025最佳论文解读|VGGT:Visual Geometry Grounded Transformer
  • 深度学习里的树模型TabNet
  • 洛谷P5250 【深基17.例5】木材仓库 (集合法)详解
  • zsn的作品集
  • 磁共振成像原理(理论)6:自由感应衰减 (Free Induction Decays)
  • 第3节-使用表格数据-CHECK约束
  • 彻底解决Qt中文乱码以及汉字编码的问题(UTF-8/GBK)
  • 【观察】傅建平:迈向“数据强国”,打通数据要素化“任督二脉”的三把钥匙
  • 一些常用的CAPL小功能
  • 当Claude Code失灵,Qwen Code能否成为你的救星?
  • Spring 项目骨架
  • C++轻量级配置管理器升级版
  • WiFi CSI标准
  • 9、从水果店账本到AI大脑:矩阵运算如何驱动现代人工智能?零基础完全指南(Transformer数学原理)
  • 外部碎片和内部碎片
  • Product Hunt 每日热榜 | 2025-09-11
  • 【前沿技术拓展Trip Two】具身智能
  • LeetCode 1658. 将x减到0的最小操作数
  • 二十二、包管理与发布 (Cargo 进阶)
  • WAF如何为你的网站筑起智能防线?
  • 【Leetcode】高频SQL基础题--1327.列出指定时间段内所有的下单产品