news 2026/4/17 16:26:24

面试官: MyBatis 核心架构解析(答案深度解析)持续更新

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
面试官: MyBatis 核心架构解析(答案深度解析)持续更新

MyBatis 核心架构:面试官想听的「不只是组件罗列」——深入本质的讲解

💡面试真实场景提醒:如果你只答出“SqlSessionFactory、SqlSession、Executor……这些组件”,面试官大概率会皱眉,然后追问:“那它们之间怎么协作?谁控制流程?谁负责缓存?谁做SQL预编译?如果我写了个@Select("select * from user where id = #{id}"),这条语句从注解到数据库返回结果,中间到底发生了什么?”
—— 所以,架构不是名词表,而是「数据与控制流的精密流水线」


一、核心架构全景图(不是静态结构,而是动态执行链)

MyBatis 的核心不是一堆独立类,而是一条分层清晰、职责分明、可插拔的执行管道。我们按一次userMapper.selectById(1)调用的完整生命周期来串讲:

Mapper接口代理对象 ↓ (JDK动态代理拦截) SqlSession(门面 + 协调中心) ↓ (委托给内部Executor) Executor(执行器:Simple/Reuse/Batch/Caching) ↓ (封装StatementHandler + ParameterHandler + ResultSetHandler) StatementHandler(真正生成 PreparedStatement / Statement) ↓ (ParameterHandler 设置参数) JDBC PreparedStatement.execute() ↓ (ResultSetHandler 封装结果) 返回 User 对象

关键认知SqlSession唯一对外暴露的入口,但它本身不干活——它像项目经理,把活分给ExecutorExecutor是真正的施工队长,再把SQL组装、参数绑定、结果映射等拆给更细的 Handler。


二、核心组件深度解析(带原理+易错点)

1.SqlSessionFactory:工厂中的“印钞机”

  • 本质:线程安全的单例工厂(通常由SqlSessionFactoryBuilder基于mybatis-config.xml和 Mapper XML 构建一次生成)。
  • 🔍干了啥?
    • 解析全局配置(事务管理器、数据源、别名、插件等);
    • 扫描并注册所有 Mapper 接口和 XML 映射文件(注意:XML 中的<select id="selectById">会被解析为MappedStatement对象,存入ConfigurationmappedStatementsMap 中,key 是namespace.methodName,如"com.xxx.UserMapper.selectById");
    • 创建SqlSession实例(每次openSession()都新建一个非线程安全的SqlSession)。

⚠️常见误区:以为SqlSessionFactory会缓存 SQL 执行结果?❌ 错!它只缓存元数据(MappedStatement、TypeHandler、ResultMap 等),不缓存任何业务数据。缓存是Executor层的事。

2.SqlSession:轻量级会话,但责任重大

  • 不是连接池,也不是 JDBC Connection 包装器(Connection 由Transaction管理);
  • ✅ 它持有一个Executor实例(默认SimpleExecutor),所有 CRUD 方法最终都转成executor.query(...)executor.update(...)
  • 自带一级缓存(Local Cache):默认开启,作用域是当前SqlSession生命周期(即openSession()close())。
    SqlSessionsession=factory.openSession();Useru1=session.selectOne("selectById",1);// 查询DB,存入一级缓存Useru2=session.selectOne("selectById",1);// 直接从一级缓存取,不查DB!

⚠️致命陷阱:在 Spring 中,若@Service方法未加@Transactional,每次@Autowired Mapper调用都会创建新SqlSession→ 一级缓存完全失效!缓存命中率=0。

3.Executor:真正的执行引擎(含二级缓存开关)

  • ✅ 三种实现:
    • SimpleExecutor:每次执行 new Statement(最简单,无重用);
    • ReuseExecutor:缓存 Statement(key 是 SQL 字符串),避免重复 prepare;
    • BatchExecutor:批量执行(addBatch()+executeBatch()),仅支持 update,不支持 select
  • 二级缓存(Second Level Cache)由 CachingExecutor 装饰实现
    • 开启条件:Mapper XML 中添加<cache/>且实体类实现Serializable
    • 缓存 key =MapperId:SQL:parameter,value = 查询结果 List;
    • 跨 SqlSession 共享(需配合@CacheNamespace或 XML<cache>);
    • ⚠️脏读风险:多个应用节点未用 Redis 等分布式缓存时,极易数据不一致!

4.StatementHandler:SQL 的“翻译官”与“执行员”

  • ✅ 核心职责:
    • 根据MappedStatement获取 SQL(支持${}拼接 /#{}预编译);
    • 创建PreparedStatement(或Statement);
    • 委托ParameterHandler设置参数(如ps.setInt(1, 1));
    • 委托ResultSetHandler处理结果集(将ResultSet映射为 Java 对象,支持resultMap复杂嵌套)。

🌟高阶理解:MyBatis 插件(Interceptor)能拦截的四大对象:ExecutorStatementHandlerParameterHandlerResultSetHandler—— 正是因为它们是执行链上最关键的“关卡”。


三、一句话总结架构灵魂

MyBatis 的核心架构 = “配置驱动的元数据中心(Configuration) + 分层解耦的执行流水线(SqlSession → Executor → StatementHandler → JDBC) + 可插拔的拦截扩展点(Plugin)”
它不做 ORM 自动映射(不像 Hibernate),而是把 SQL 控制权交还给开发者,用最小侵入的方式,把 JDBC 的模板代码彻底消灭

(字数:约 1080 字)
更多Java面试题整理:

JVM面试题
MySQL面试题
Redis面试题
Spring面试题

完整面试题库:
https://myquotego.com/html/questions?_from=csdn_123_4

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 16:24:37

避开SAP月结大坑:物料分类账CKM3的5个常见错误配置与修复指南

避开SAP月结大坑&#xff1a;物料分类账CKM3的5个常见错误配置与修复指南 每到月底关账时&#xff0c;SAP系统里的物料分类账就像个定时炸弹&#xff0c;稍有不慎就会让整个月结流程陷入混乱。作为经历过无数次"救火"的SAP顾问&#xff0c;我见过太多因为CKM3配置不当…

作者头像 李华
网站建设 2026/4/17 16:23:18

AI+BI如何让一线业务人员不用懂SQL也能做分析?3个落地案例验证

三个高频业务场景&#xff0c;问问你是否似曾相识 场景一&#xff1a; 区域销售经理想查过去3个月华东区新品的动销率&#xff0c;还要对比同周期老品数据。他要等3天走数据团队的排期&#xff0c;才能拿到这份报告。 场景二&#xff1a; 门店店长想知道上周到店客群的复购转化…

作者头像 李华
网站建设 2026/4/17 16:23:10

3分钟快速上手:使用Vue+SVG构建专业网络拓扑图

3分钟快速上手&#xff1a;使用VueSVG构建专业网络拓扑图 【免费下载链接】easy-topo vuesvgelement-ui 快捷画出网络拓扑图 项目地址: https://gitcode.com/gh_mirrors/ea/easy-topo easy-topo是一个基于Vue.js和SVG技术的轻量级网络拓扑图绘制工具&#xff0c;专为开发…

作者头像 李华