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 注入。
相关推荐
摇滚侠3 小时前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
麦聪聊数据5 小时前
数据服务化时代:企业数据能力输出的核心路径
数据库
ApacheSeaTunnel5 小时前
实战演示 | 基于 Apache SeaTunnel 与 Apache DolphinScheduler 实现 MySQL 到 Doris 离线定时增量同步
大数据·mysql·开源·doris·数据集成·seatunnel·数据同步
shushangyun_5 小时前
2026年快消品B2B系统推荐:支持终端门店订货、促销政策自动化的工具?
java·运维·网络·数据库·人工智能·spring·自动化
DARLING Zero two♡5 小时前
【MySQL数据库】数据类型与表约束
数据库·mysql
曹牧6 小时前
Oracle EXPLAIN PLAN
数据库·oracle
BD_Marathon6 小时前
SQL学习指南——视图
数据库·sql
活宝小娜6 小时前
mysql详细安装教程
数据库·mysql·adb
贤时间6 小时前
codex 助力oracle ebs 开发
数据库·oracle
秉承初心6 小时前
PostgreSQL 数据性能瓶颈突破实战
数据库·postgresql·oracle