MyBatis-Plus 的加载及初始化

在 Spring Boot 启动过程中,MyBatis-Plus 的加载和初始化涉及多个阶段的工作。这些工作包括 MyBatis-Plus 自身的配置解析、Mapper 接口的扫描与注册、SQL 语句的动态注入以及底层 MyBatis 的初始化等。以下是对整个过程的详细分析:


1. Spring Boot 启动时对 MyBatis-Plus 的加载

Spring Boot 在启动时会对 MyBatis-Plus 进行自动配置(AutoConfiguration),并通过依赖注入的方式完成组件的初始化。以下是关键步骤:

(1)@EnableAutoConfiguration 和 MybatisPlusAutoConfiguration
  • Spring Boot 的核心特性是基于约定优于配置的原则,通过 @EnableAutoConfiguration 注解自动加载相关的 Starter 配置。
  • mybatis-plus-boot-starter 提供了 MybatisPlusAutoConfiguration 类,该类负责完成 MyBatis-Plus 的自动配置。
主要功能:
  • 数据源配置:加载 DataSource,并将其注入到 MyBatis 中。
  • SqlSessionFactory 初始化:创建 SqlSessionFactory 对象,用于管理 SQL 会话。
  • Mapper 扫描:扫描标注了 @Mapper 或被 @MapperScan 指定的包路径下的所有 Mapper 接口,并将其注册为 Spring 容器中的 Bean。
  • 全局配置:读取 application.yml 或 application.properties 中的 MyBatis-Plus 配置项(如分页插件、逻辑删除配置等)。
(2)MapperScannerConfigurer 的作用
  • MyBatis-Plus 使用 MapperScannerConfigurer 来扫描所有的 Mapper 接口。
  • 扫描到的每个 Mapper 接口都会被注册为一个 Spring Bean,并与底层的 MyBatis 映射器绑定。
(3)SqlSessionTemplate 和 SqlSession 的初始化
  • Spring Boot 会创建 SqlSessionTemplate,它是 MyBatis 的核心组件之一,用于执行 SQL 语句。
  • SqlSessionTemplate 内部封装了 SqlSession,并通过线程安全的方式管理数据库连接。

2. MyBatis-Plus 的加载和初始化

MyBatis-Plus 在 Spring Boot 启动时完成了自身的初始化工作,主要包括以下几个方面:

(1)全局配置加载

MyBatis-Plus 会从配置文件中读取全局配置项,例如:

  • 数据库字段命名规则(驼峰命名或下划线命名)。
  • 主键生成策略。
  • 字段自动填充策略。
  • 分页插件、逻辑删除插件等。

配置项通常通过 application.ymlapplication.properties 提供,例如:

yaml

mybatis-plus:global-config:db-config:table-underline: true  # 启用驼峰命名规则id-type: auto          # 主键生成策略
(2)Mapper 接口的动态代理

MyBatis-Plus 会为每个 Mapper 接口生成动态代理对象。这些代理对象实现了接口中定义的方法,并通过 MyBatis 的底层机制执行 SQL 操作。

动态代理的核心逻辑:
  • 方法拦截:当调用 Mapper 接口中的方法时,动态代理会拦截调用,并根据方法签名生成对应的 SQL 语句。
  • SQL 注入:如果启用了自定义 SQL 注入器(如 InsertBatchSomeColumn),则会在启动时将这些方法的 SQL 注入到 MyBatis 的 MappedStatement 中。
(3)SQL 方法的动态注入

MyBatis-Plus 提供了许多内置的通用方法(如 insertselectById 等),这些方法对应的 SQL 语句是在启动时动态生成并注入到 MyBatis 的 MappedStatement 中的。

动态注入的过程:
  1. 扫描 Mapper 接口:MyBatis-Plus 会扫描所有的 Mapper 接口,并为其注册默认的 SQL 方法。
  2. 生成 SQL 语句:对于每个方法,MyBatis-Plus 会根据方法签名和实体类的元信息(如表名、字段名)动态生成 SQL 语句。
  3. 注入 MappedStatement:生成的 SQL 语句会被注入到 MyBatis 的 MappedStatement 中,供后续执行使用。
(4)插件的初始化

MyBatis-Plus 提供了许多内置插件(如分页插件、逻辑删除插件等),这些插件会在启动时被初始化并注册到 MyBatis 的拦截器链中。

常见插件:
  • 分页插件(PaginationInterceptor):用于支持分页查询。
  • 逻辑删除插件(LogicSqlInjector):用于支持逻辑删除功能。
  • 性能分析插件(PerformanceInterceptor):用于分析 SQL 执行性能。

插件的初始化通常通过配置文件或代码显式注册,例如:

@Bean
public PaginationInterceptor paginationInterceptor() {return new PaginationInterceptor();
}


3. 底层 MyBatis 的初始化

MyBatis 是 MyBatis-Plus 的底层框架,因此 MyBatis-Plus 的初始化也依赖于 MyBatis 的核心机制。以下是 MyBatis 的初始化过程:

(1)SqlSessionFactory 的创建
  • SqlSessionFactory 是 MyBatis 的核心组件,用于创建 SqlSession 对象。
  • 在 Spring Boot 中,SqlSessionFactory 通常通过 SqlSessionFactoryBean 创建。
初始化流程:
  1. 加载 MyBatis 配置文件:读取 mybatis-config.xml 或通过 Java 配置类提供的配置项。
  2. 解析 Mapper XML 文件:如果存在 XML 格式的 Mapper 文件,MyBatis 会解析这些文件并将其中的 SQL 语句注册到 MappedStatement 中。
  3. 创建 SqlSessionFactory 实例:完成上述步骤后,SqlSessionFactory 被创建并注入到 Spring 容器中。
(2)MapperRegistry 的初始化
  • MapperRegistry 是 MyBatis 的一个内部组件,用于管理所有的 Mapper 接口。
  • 在启动时,MyBatis 会将所有的 Mapper 接口注册到 MapperRegistry 中。
(3)Configuration 的初始化
  • Configuration 是 MyBatis 的核心配置对象,包含所有的全局配置项和映射信息。
  • 在启动时,MyBatis 会初始化 Configuration 对象,并将所有的 MappedStatement、插件、类型处理器等注册到其中。

4. 总结:工作原理及底层逻辑

以下是 Spring Boot 启动时 MyBatis-Plus 的加载和初始化过程的总结:

  1. Spring Boot 自动配置

    • 加载 DataSource
    • 初始化 SqlSessionFactory
    • 扫描并注册 Mapper 接口。
  2. MyBatis-Plus 的初始化

    • 加载全局配置项。
    • 动态生成并注入 SQL 方法。
    • 初始化插件(如分页插件、逻辑删除插件)。
  3. MyBatis 的底层初始化

    • 创建 SqlSessionFactory
    • 解析 Mapper XML 文件。
    • 初始化 MapperRegistry 和 Configuration
  4. 运行时行为

    • 当调用 Mapper 接口中的方法时,动态代理会拦截调用,并通过 MyBatis 的底层机制执行 SQL 操作。

MyBatis-Plus 在 Spring Boot 启动时会完成实体类的基础 SQL(如 SELECTINSERTUPDATEDELETE 等)的组装和加载,并将这些 SQL 注册到 MyBatis 的 Mapper 映射中。这个过程可以理解为 提前初始化好基础 SQL,以便在运行时直接使用。

以下是详细的分析和工作原理:


1. 基础 SQL 的组装

MyBatis-Plus 通过动态生成的方式,为每个实体类生成一组通用的基础 SQL(即 CRUD 操作对应的 SQL)。这些 SQL 是基于实体类的注解(如 @TableName@TableField)以及全局配置(如字段命名规则、主键策略等)动态生成的。

(1)SQL 的生成逻辑

MyBatis-Plus 使用 AbstractMethod 类及其子类来定义每种 SQL 方法的生成逻辑。例如:

  • Insert 方法:生成插入语句(INSERT INTO table_name (column1, column2) VALUES (?, ?))。
  • SelectById 方法:生成根据主键查询的语句(SELECT * FROM table_name WHERE id = ?)。
  • Update 方法:生成更新语句(UPDATE table_name SET column1 = ?, column2 = ? WHERE id = ?)。
  • Delete 方法:生成删除语句(DELETE FROM table_name WHERE id = ?)。

这些方法的具体实现位于 com.baomidou.mybatisplus.core.injector.methods 包中。

(2)动态生成 SQL

MyBatis-Plus 会根据实体类的元信息(如表名、字段名、主键等)动态生成 SQL 语句。例如:

  • 如果实体类中有 @TableName("user") 注解,则生成的 SQL 中的表名为 user
  • 如果字段上有 @TableField("name") 注解,则生成的 SQL 中的字段名为 name
  • 如果启用了驼峰命名规则(table-underline: true),则会自动将字段名从驼峰命名转换为下划线命名。

2. SQL 的注册过程

生成的基础 SQL 会被注册到 MyBatis 的 MappedStatement 中,这是 MyBatis 的核心组件之一,用于存储 SQL 语句及其映射信息。

(1)什么是 MappedStatement

MappedStatement 是 MyBatis 的一个内部对象,用于描述一条 SQL 语句的执行细节,包括:

  • SQL 语句本身。
  • 参数类型。
  • 返回值类型。
  • 执行器类型(如 SIMPLEREUSEBATCH)。
(2)SQL 注册的流程

在 Spring Boot 启动时,MyBatis-Plus 会完成以下步骤:

  1. 扫描 Mapper 接口:通过 @MapperScan 或 MapperScannerConfigurer 扫描所有的 Mapper 接口。
  2. 生成 SQL:为每个 Mapper 接口中的方法动态生成 SQL 语句。
  3. 注册到 MappedStatement:将生成的 SQL 注册到 MyBatis 的 Configuration 对象中,并与对应的 Mapper 方法绑定。
示例:

假设有一个实体类 User 和对应的 UserMapper

@TableName("user")
public class User {private Long id;private String name;
}public interface UserMapper extends BaseMapper<User> {
}

在启动时,MyBatis-Plus 会为 UserMapper 注册以下基础 SQL:

  • SELECT * FROM user WHERE id = ?selectById 方法)
  • INSERT INTO user (id, name) VALUES (?, ?)insert 方法)
  • UPDATE user SET name = ? WHERE id = ?updateById 方法)
  • DELETE FROM user WHERE id = ?deleteById 方法)

这些 SQL 会被存储在 MappedStatement 中,并与 UserMapper 的方法绑定。


3. 提前初始化的好处

MyBatis-Plus 的这种提前初始化机制有以下好处:

(1)性能优化
  • 减少运行时开销:SQL 语句在启动时就已经生成并注册,运行时无需再动态生成 SQL,从而提高了执行效率。
  • 缓存复用MappedStatement 是 MyBatis 的缓存对象,同一 SQL 语句在多次调用时可以直接复用,避免重复解析。
(2)简化开发
  • 零配置:开发者无需手动编写 SQL 语句,MyBatis-Plus 会根据实体类自动生成基础 SQL。
  • 统一管理:所有基础 SQL 都由 MyBatis-Plus 统一生成和管理,减少了代码冗余和潜在错误。
(3)灵活性
  • 可扩展性:如果需要自定义 SQL 方法,可以通过实现 AbstractMethod 或自定义 SqlInjector 来扩展功能。
  • 插件支持:MyBatis-Plus 的插件机制(如分页插件、逻辑删除插件)可以在 SQL 注册过程中对生成的 SQL 进行增强或修改。

4. 动态代理与运行时行为

虽然基础 SQL 在启动时已经生成并注册,但实际的 SQL 执行是由 MyBatis 的动态代理机制完成的。以下是运行时的行为:

(1)动态代理拦截

当调用 Mapper 接口中的方法时,MyBatis 的动态代理会拦截调用,并根据方法签名找到对应的 MappedStatement

(2)参数绑定

MyBatis 会根据方法的参数类型和 SQL 中的占位符(?)进行参数绑定。例如:

java

User user = userMapper.selectById(1L);

在运行时,MyBatis 会将 1L 绑定到 SQL 中的 ?,生成最终的 SQL:

sql

SELECT * FROM user WHERE id = 1;

(3)执行 SQL

绑定参数后,MyBatis 会通过 SqlSession 执行 SQL,并返回结果。


5. 总结

  • SQL 的组装:MyBatis-Plus 在启动时会根据实体类的元信息动态生成基础 SQL(如 SELECTINSERTUPDATEDELETE 等)。
  • SQL 的注册:生成的 SQL 会被注册到 MyBatis 的 MappedStatement 中,并与 Mapper 方法绑定。
  • 提前初始化的好处:这种方式减少了运行时的开销,简化了开发,并提供了良好的灵活性和扩展性。

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

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

相关文章

SpringBoot中安全的设置阿里云日志SLS的accessKey

众所周知,阿里云的服务都是基于accesskeyId和accesskeySecret来进行身份鉴权的,但唯独日志因为需要写入到.xml文件里对于accesskeyId和accesskeySecret需要进行一定程度的改进,尤其是使用了jasypt进行加密的参数传递进去logback.xml更是会遇到需要对参数进行解密的问题,而官网只…

关于解决Ubuntu终端及系统字体大小的问题

在Ubuntu中调整终端和系统字体大小可以通过以下方法&#xff08;可能不仅仅只是这几种&#xff09;实现&#xff1a; 1. 调整系统字体大小 打开终端并输入以下命令&#xff0c;安装GNOME Tweaks&#xff0c;等待安装完成&#xff1a; sudo apt install gnome-tweaks 接着进行…

Rust vs. Go: 性能测试(2025)

本内容是对知名性能评测博主 Anton Putra Rust vs. Go (Golang): Performance 2025 内容的翻译与整理, 有适当删减, 相关数据和结论以原作结论为准。 再次对比 Rust 和 Go&#xff0c;但这次我们使用的是最具性能优势的 HTTP 服务器库---Hyper&#xff0c;它基于 Tokio 异步运…

【NLP 48、大语言模型的神秘力量 —— ICL:in context learning】

目录 一、ICL的优势 1.传统做法 2.ICL做法 二、ICL的发展 三、ICL成因的两种看法 1.meta learning 2.Bayesian Inference 四、ICL要点 ① 语言模型的规模 ② 提示词prompt中提供的examples数量和顺序 ③ 提示词prompt的形式&#xff08;format&#xff09; 五、fine-tune VS I…

两数之和解题记录

开始打算用一个数组保存差值&#xff0c;arr[target-nums[i]] i, 只要arr[nums[i]]有内容就能满足target&#xff0c;返回arr[nums[i]]和i。但是会出现复数的情况&#xff0c;所以换成map。 换成map就只用一边遍历&#xff0c;一遍检查和存入对应key就行了&#xff0c;value就…

P1722 矩阵Ⅱ - 洛谷

题源&#xff1a;P1722 矩阵 II - 洛谷 看了题目之后&#xff0c;需要注意的是&#xff1a; ①在1 ~ i 个格子中红色数量 > 黑色数量 ②最后&#xff0c;在2 * n 个格子中&#xff0c;红色数量 黑色数量 根据这两个约束条件&#xff0c;可以知道&#xff0c;第一个格…

数据库——MySQL基础操作

一、表结构与初始数据 假设存在以下两张表&#xff1a; 1. student 表 字段名数据类型描述idINT学生唯一标识符nameVARCHAR(100)学生姓名ageINT学生年龄sexVARCHAR(10)学生性别 初始数据&#xff1a; idnameagesex1张三20男2李四22女3王五21男 2. course 表 字段名数据类…

行业白皮书2025 | 益企研究院:AI时代的存储基石

在当今科技飞速发展的时代&#xff0c;AI技术已成为推动各行业变革的关键力量。日前&#xff0c;益企研究院重磅发布《AI时代的存储基石》白皮书。 下载方式&#xff1a;关注“渡江客涂鸦板”&#xff0c;回复st250326获取免费下载地址 数据需求与技术挑战&#xff1a; AI技术…

音视频新人如何快速上手nginx-rtmp-module

一、整体设计架构 nginx-rtmp-module 是 Nginx 的一个扩展模块&#xff0c;专门为 Nginx 添加了对 RTMP 协议的支持。其核心功能包括&#xff1a; RTMP推流&#xff08;publish&#xff09; RTMP拉流&#xff08;play&#xff09; 流转发&#xff08;relay&#xff09; 流录…

vue 封装 Axios菜鸟教程

1、Axios依赖下载 $ npm install axios 2、以下链接为Axios 的api Axios 实例 | Axios中文文档 | Axios中文网 3、 项目新建request.js&#xff0c;文件名称按照驼峰命名法就可以 4、封装request.js代码如下 import axios from "axios"//创建axios实例&#xff0…

[项目]基于FreeRTOS的STM32四轴飞行器: 十一.MPU6050配置与读取

基于FreeRTOS的STM32四轴飞行器: 十一.MPU6050 一.芯片介绍二.配置I2C三.编写驱动四.读取任务的测试五.MPU6050六轴数据的校准 一.芯片介绍 芯片应该放置在PCB中间&#xff0c;X Y轴原点&#xff0c;敏感度131表示范围越小越灵敏。理想状态放置在地面上X&#xff0c;Y&#xf…

iOS常见网络框架

URLSession、Alamofire 和 Moya 1. URLSession 1.1 核心概念 URLSession 是 Apple 官方提供的网络请求 API&#xff0c;封装在 Foundation 框架中。它支持 HTTP、HTTPS、FTP 等协议&#xff0c;可用于&#xff1a; ​ • 普通网络请求&#xff08;GET/POST&#xff09; ​ …

AOA(到达角度)与TOA(到达时间)两个技术的混合定位,MATLAB例程,自适应基站数量,三维空间下的运动轨迹,滤波使用UKF(无迹卡尔曼滤波)

本文介绍一个MATLAB代码,实现了三维动态目标非线性定位与滤波系统,通过融合 到达角(AOA) 和 到达时间(TOA) 的混合定位方法,结合 无迹卡尔曼滤波(UKF) 处理非线性观测模型,优化轨迹精度。代码支持自适应基站数量配置,适用于复杂非线性场景的定位研究。 文章目录 运行…

Ubuntu 重置密码方法

目录 修改过 root 密码&#xff0c;重置密码的方法没改过 root 密码‌&#xff0c;重置密码的方法 修改过 root 密码&#xff0c;重置密码的方法 Ubuntu 默认禁用root用户&#xff0c;意思就是安装好Ubuntu系统后&#xff0c;root用户默认是没有密码的&#xff0c;普通用户通过…

Leetcode 路径总和 III

java 解法一&#xff1a;双递归 class Solution {public int pathSum(TreeNode root, long targetSum) { //外层递归,把每个节点都当作路径起点if(root null) return 0;int ret rootSum(root, targetSum);ret pathSum(root.left, targetSum);ret pathSum(root.right, targ…

WEB安全--SQL注入--利用log写入webshell

一、原理&#xff1a; 这也是对之前文章的补充&#xff1a;WEB安全--SQL注入--INTO OUTFILE-CSDN博客 我们可以通过修改MySQL的log文件&#xff0c;用select关键字写入木马文件放在服务器物理地址中&#xff0c;通过访问物理地址getshell。 二、条件&#xff1a; 用户有写入权限…

C++11中引入的比较常用的新特性讲解(上)

目录 1、C11简介 2、统一的列表初始化 2.1、&#xff5b;&#xff5d;初始化 2.2、std::initializer_list 3、变量类型推导 3.1、auto 3.2、decltype 3.3、nullptr 4、范围for循环 5、STL中一些变化 6、右值引用和移动语义 6.1、左值引用和右值引用 6.2、右值引用…

hugo+github pages 部署实验室网站

&#xff01;&#xff01;太爽了&#xff0c;看了很久教程&#xff0c;自己试了好久&#xff0c;终于搞懂怎么把hugo和public单独进行部署了&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 目的是什么&#xff1f;目的当然是为了修改这天杀的hugo的模板。现在…

两头文件互引问题解决(前置声明)

问题&#xff1a; 想必正在基础阶段学习的朋友们都遇见过以下问题吧 widget.h otherwidget.h 如上问题是&#xff0c;我在widget.h中引用了otherwidget.h ,在ohterwidget中又引用了widget.h&#xff0c;两个头文件互相引用产生了报错 解决办法&#xff1a; 那么我们该如何解…

Python 异常处理完全指南

目录 一、异常处理基础1. 基本语法结构 二、常见异常类型1. 内置异常层次2. 常见异常示例 三、多重异常处理1. 合并捕获2. 分层处理 四、finally与else子句1. finally 应用场景2. else 使用技巧 五、自定义异常1. 创建异常类2. 异常继承体系 六、异常链与上下文1. raise from 语…