MyBatis 与 MySQL 执行流程

一、MyBatis 执行流程

MyBatis 是 Java 持久层框架,它负责把 Java 代码中的数据库操作,转化为可执行的 SQL 并与数据库交互。

1. 读取配置文件

  • 读取 MyBatis 全局配置文件(sqlMapConfig.xml/mybatis-config.xml)和所有 Mapper 映射文件。
  • 全局配置文件:包含数据库连接信息、事务、别名、日志、插件等配置。
  • Mapper 映射文件:包含具体 SQL 语句、参数映射、结果集映射规则。

2. 构建 SqlSessionFactory 对象

  • MyBatis 通过配置文件解析器,将所有配置信息加载到内存,构建出 SqlSessionFactory
  • SqlSessionFactory 是工厂类,全局唯一,负责创建 SqlSession,它相当于数据库连接池的入口。

3. 创建 SqlSession 对象

  • SqlSessionFactory 创建 SqlSession 对象,它代表一次数据库会话,包含了数据库连接、事务控制、执行 SQL 的能力。
  • SqlSession 是 MyBatis 操作数据库的核心对象,是非线程安全的,每次数据库操作都应创建独立实例。

4. 获取 Mapper 代理对象

  • 通过 SqlSession.getMapper(XXXMapper.class) 获取 Mapper 接口的代理对象。
  • 代理对象会自动绑定 Mapper 映射文件中的 SQL 语句,让开发者可以通过调用接口方法执行数据库操作,无需手动写 JDBC 代码。

5. 执行数据库操作

  • 调用 Mapper 接口的方法时,代理对象会解析对应的 SQL 语句,完成参数绑定、SQL 预编译,再通过 SqlSession 执行增删改查操作。
  • SqlSession 内部封装了 JDBC 的 ConnectionStatement,与数据库建立连接并执行 SQL。

6. 结果映射与会话关闭

  • 数据库返回的结果集,会根据 Mapper 映射文件中的规则,自动映射为 Java 对象。
  • 操作完成后,关闭 SqlSession,释放数据库连接资源。

二、MySQL 执行流程(以 MyBatis 场景为例)

MyBatis 生成的 SQL 最终会发送给 MySQL 服务器,MySQL 内部会按以下流程处理请求:

1. SQL 与参数拼接(MyBatis 层准备)

  • MyBatis 将用户传入的参数,与 Mapper 映射文件中的 SQL 模板进行预编译拼接(#{} 会生成预编译语句,防止 SQL 注入),生成完整可执行的 SQL 语句。

2. 连接器(Connection)处理

  • MySQL 服务器接收客户端(MyBatis)的连接请求,建立 TCP 连接,分配线程处理该请求。
  • 进行用户身份验证、权限校验,确认该用户有执行当前 SQL 的权限。

3. 查询缓存(可选)

  • MySQL 会先检查查询缓存(MySQL 8.0 已移除该功能),如果缓存中存在完全相同的 SQL 及其结果,直接返回缓存数据,跳过后续流程。

4. SQL 解析与预处理

  • 解析器对 SQL 语句进行词法、语法分析,生成抽象语法树(AST),验证 SQL 语法是否合法。
  • 预处理阶段会检查表、字段是否存在,用户权限是否匹配。

5. 查询优化器(Optimizer)优化

  • 优化器根据统计信息,生成多种执行方案,选择最优的执行计划(比如选择合适的索引、决定表连接顺序)。
  • 生成执行计划后,将其传递给执行器。

6. 执行器(Executor)执行 SQL

  • 执行器调用存储引擎的接口,按照优化后的执行计划,向存储引擎请求数据。
  • 对于 DML 语句(增删改),会执行对应的写操作;对于 DQL 语句(查询),会读取数据。

7. 存储引擎处理

  • 以 InnoDB 为例:
    1. 优先从缓冲池(Buffer Pool)中读取数据页,若不存在则从磁盘加载数据页到缓冲池。
    2. 执行事务操作,记录 Redo Log(重做日志)和 Undo Log(回滚日志),保证事务的 ACID 特性。
    3. 写操作会先写入缓冲池,再通过刷盘机制持久化到磁盘。

8. 结果返回

  • 存储引擎将数据返回给执行器,执行器将结果集返回给客户端(MyBatis)。
  • MyBatis 再将结果集映射为 Java 对象,完成整个流程。

三、面试高频考点补充

  1. #{}${} 的区别

    • #{}:预编译处理,SQL 中的参数会被替换为 ?,使用 PreparedStatement 赋值,防止 SQL 注入,推荐使用。
    • ${}:直接字符串拼接,不会预编译,存在 SQL 注入风险,仅适用于表名、列名等动态场景。
  2. MyBatis 一级缓存与二级缓存

    • 一级缓存:SqlSession 级别缓存,默认开启,同一会话内相同查询直接从缓存取数据,会话关闭则缓存失效。
    • 二级缓存:Mapper 级别缓存,跨 SqlSession 共享,需手动配置开启,适用于多会话场景。
  3. MySQL 预编译的作用

    • 预编译语句(PreparedStatement)会将 SQL 模板提前发送给数据库,后续仅发送参数,数据库可复用执行计划,提升效率,同时防止 SQL 注入。
相关推荐
l1t2 小时前
DeepSeek总结的将 Rust Delta Kernel 集成到 ClickHouse
数据库·clickhouse·rust
qq_283720052 小时前
万字深度:Chroma 向量数据库全解析 — 核心原理、实战操作、性能优化与工程最佳实践
数据库·性能优化
黄筱筱筱筱筱筱筱3 小时前
二进制包安装MySql服务
数据库
初心未改HD3 小时前
LLM应用开发之向量数据库详解
数据库·人工智能
键盘上的猫头鹰3 小时前
【从零学MySQL(三)】数据增删改(DML)及 SELECT 查询详解
数据库·mysql·数据分析
KaMeidebaby3 小时前
卡梅德生物技术快报|蛋白的过表达质粒构建与生信分析实验全流程复盘
前端·数据库·其他·百度·新浪微博
渣渣盟4 小时前
数据库之两段锁协议相关理论及应用
数据库·关系规范化·两段锁协议
LCG元4 小时前
Istio - 服务网格流量治理深度解析:灰度发布 / 故障注入配置实践
java·数据库·istio