在Java后端面试中,MyBatis的工作原理几乎是高频考点。很多同学容易混淆「启动加载」和「请求处理」两大阶段,分不清SqlSession、Executor、MappedStatement等核心组件的作用。
一、MyBatis启动加载阶段(程序启动仅执行1次)
核心作用:提前解析所有配置与SQL,初始化环境,创建全局工厂,避免每次操作数据库重复加载资源。
1.1 SqlSessionFactory 的创建过程
-
核心职责:加载并解析
mybatis-config.xml全局配置文件、所有Mapper映射文件,将数据库连接、环境、映射规则等配置统一存入Configuration全局容器。 -
关键核心:项目启动时,会自动解析Mapper中每一条
select/insert/update/delete标签,将每条SQL单独封装为MappedStatement对象 ,统一交由Configuration管理。 -
底层实现:通过
SqlSessionFactoryBuilder构建SqlSessionFactory,底层实现类为DefaultSqlSessionFactory。 -
关键作用:
SqlSessionFactory全局唯一,整个项目只创建一次,是生产SqlSession的核心工厂。
1.2 SqlSession 的获取
-
获取方式:通过
SqlSessionFactory.openSession()创建会话对象。 -
底层实现:默认创建
DefaultSqlSession,是我们操作数据库的直接入口。 -
重要特性:
SqlSession非线程安全,单次数据库请求独立创建,使用完毕必须关闭释放资源。 -
补充说明:
SqlSession只提供通用增删改查模板方法,不存储我们自定义的业务SQL。
二、MyBatis请求处理阶段(每次操作数据库都会执行)
每次调用增删改查方法,都会触发该套流程:方法调用 → 缓存判断 → 加载SQL信息 → 处理参数 → 执行SQL → 结果封装。
2.1 SqlSession 的核心处理方法
SqlSession封装了MyBatis通用的数据库操作方法,覆盖全部CRUD场景:
-
查询:
selectOne、selectList -
新增:
insert -
修改:
update -
删除:
delete
我们编写的自定义SQL、业务方法,依靠statementId绑定对应Mapper配置,SqlSession仅负责调用入口,不保存具体SQL语句。
2.2 Executor 执行器(核心调度者)
SqlSession不会直接操作数据库,所有请求都会委派给底层Executor执行器,它是MyBatis的调度核心,负责事务管理与缓存处理。
1. 缓存核心规则(重点修正)
-
一级缓存:默认自动开启,无需任何配置 ,作用域为当前
SqlSession会话,会话内重复查询自动命中; -
二级缓存:默认关闭,必须手动添加<cache/>配置才会生效,作用域为同一个Mapper,跨会话共享;
2. 缓存执行顺序
-
手动开启二级缓存:执行顺序 → 二级缓存 → 一级缓存;
-
项目默认无二级缓存:直接跳过二级缓存,只查询一级缓存;
3. 执行逻辑
缓存命中直接返回数据;只有两级缓存全部未命中时,才会访问数据库。
4. 常见实现类
SimpleExecutor(默认)、ReuseExecutor、BatchExecutor。
面试常考点:
一级缓存开箱即用,二级缓存因数据一致性问题,实际开发极少使用。
2.3 MappedStatement(SQL信息唯一载体)
缓存未命中后,Executor根据传入的statementId,从Configuration容器中匹配并获取对应的MappedStatement。
-
生成时机:程序启动阶段提前解析生成;
-
存储内容:封装完整SQL语句、参数类型、
resultMap/resultType映射规则、SQL唯一标识; -
核心价值:MyBatis执行SQL的唯一依据,统一管理所有SQL配置,避免重复解析。
2.4 StatementHandler 数据处理与SQL执行
Executor获取MappedStatement后,将JDBC交互、参数处理、SQL执行全部交给StatementHandler完成:
- 参数预处理
通过ParameterHandler解析SQL中#{}占位符,完成Java参数与JDBC参数转换,有效防止SQL注入。
- 执行数据库SQL
依托JDBC的PreparedStatement,向数据库发送编译完成的SQL语句并执行。
- 结果集自动映射
数据库返回ResultSet原始结果集,由ResultSetHandler根据配置规则,自动封装为Java实体类、List集合,最终返回给业务层。
三、MyBatis完整执行流程图
开启
未开启
命中
未命中
程序启动
加载全局配置+所有Mapper
每条SQL封装为MappedStatement
创建全局唯一SqlSessionFactory
openSession 创建SqlSession
调用SqlSession通用CRUD方法
委派底层Executor执行器
二级缓存?未配置则自动跳过
查询二级缓存
直接查询一级缓存
缓存是否命中
直接返回数据
根据statementId获取MappedStatement
StatementHandler接管执行
ParameterHandler 处理入参
JDBC执行SQL语句
ResultSetHandler 封装结果
返回Java对象 关闭SqlSession
四、面试高频考点总结
- 启动流程
解析配置文件 → 初始化Configuration → 封装MappedStatement → 创建SqlSessionFactory。
-
单次请求完整流程
SqlSession调用方法 →Executor调度缓存 → 获取MappedStatement→StatementHandler执行SQL → 参数处理 → 结果映射返回。 -
缓存核心考点
-
一级缓存:默认开启、会话级别、无需配置;
-
二级缓存:默认关闭、Mapper级别、需手动配置;
-
无二级缓存时,只走「一级缓存 → 数据库」。
- 核心对象职责
-
SqlSessionFactory:全局唯一工厂,生产SqlSession; -
SqlSession:数据库会话,提供通用CRUD方法,非线程安全; -
Executor:底层调度中心,管理缓存与事务; -
MappedStatement:封装所有SQL与映射规则; -
StatementHandler:对接JDBC,完成参数处理与结果封装。
结尾
本文完整还原MyBatis真实执行流程,修正了缓存配置误区,补齐MappedStatement核心知识点,流程连贯、逻辑严谨,可直接用于学习、笔记与面试复习。