MyBatis 架构大起底:这三层不懂,别说你用过它!

14 阅读5分钟



“小米,我周末又面了一个岗位,面试官问我:‘MyBatis的功能架构是怎么分层的?各层干嘛的?’我一下脑子空白了,只说出一句‘呃……有XML和接口’,然后就没有然后了。”

这是我上周五接到的一个私信。

看到这条消息,我嘴角一翘,熟悉的社招味儿扑面而来。

社招面试,不止考你“会用”,更要你“知其然,也知其所以然”。MyBatis 作为我们常用的持久层框架,面试中频频出场,而“功能架构”这个问题,更是个经典深水炸弹。

今天,我就用一个讲故事的方式,带你真正吃透 MyBatis 的三层架构,解构它的每一层职责、内部机制,以及面试时你该怎么回答!

故事开头:一位求职Java工程师的灵魂三问

话说小米有个朋友,叫小李,是个有3年开发经验的Java程序员。

这段时间小李在准备社招跳槽,每天不是在投简历、就是在准备八股文。可他心里总是发虚,尤其是提到框架底层原理时。他常说:

“MyBatis我一直在用啊,就是配个XML,写个接口,它就能查数据库了嘛。还能怎么分层?”

哎,小李啊,你只看到了冰山一角!

MyBatis 作为一款优秀的 ORM 框架,其内部结构其实很清晰、也很精巧。我们把它的功能架构大致分为三层:

MyBatis的三层架构概览

这三层分别是:

  • API接口层:对开发者暴露的入口,用于操作 MyBatis。
  • 数据处理层:负责 SQL 的构建、参数映射、结果集封装等核心逻辑。
  • 基础支撑层:底层资源管理,事务控制、数据库连接池、插件机制等。

这三层,就像一家公司:

  • API层 是前台业务员,负责跟客户(我们开发者)打交道;
  • 数据处理层 是核心运营部门,负责处理各种“订单”(SQL);
  • 基础支撑层 是后勤部门,确保服务器、电力、物流一切OK。

是不是有点意思?别急,我们一层层拆开讲。

第一层:API接口层(你最熟的那一层)

关键词:SqlSession、Executor、Configuration

这层,是你平时跟 MyBatis 打交道最直接的“窗口”。

就比如:

你每次写的 SqlSession、selectOne、insert,都是在调用 API 接口层提供的功能。

这一层干嘛的?

  • 暴露操作数据库的方法,如 selectOne、selectList、update、delete。
  • 提供配置入口,如注册 Mapper 接口、配置数据源等。
  • 承担了“事务管理”和“生命周期管理”的重要角色。

面试官可能问:

  • SqlSession 是线程安全的吗?
  • Executor 是做什么的?有哪些实现?

答案:

  • SqlSession不是线程安全的,每个线程都应有独立实例。
  • Executor 是用来执行 SQL 语句的执行器,有三种实现:
    • SimpleExecutor(默认)
    • ReuseExecutor(SQL 重用)
    • BatchExecutor(批处理)

你能说到这个层次,面试官一定会眼前一亮。

第二层:数据处理层(MyBatis 的心脏)

关键词:MappedStatement、BoundSql、ParameterHandler、ResultSetHandler

这一层,是 MyBatis 真正“干活”的地方!

你写的 XML 映射文件、注解 SQL,最终都会被解析成内部的 MappedStatement,并在这里执行。

它做了什么?

我们分步骤来看:

  • SQL构建:根据映射语句、参数构造出 BoundSql。
  • 参数处理:由 ParameterHandler 把 Java 对象转换成 SQL 参数。
  • SQL执行:通过 Executor 执行具体 SQL。
  • 结果映射:ResultSetHandler 把结果集转换成 Java 对象。

想象一个流程:

  • 你写了 select * from user where id = #{id}

MyBatis 会:

  • 解析这条语句,生成 MappedStatement。
  • 用你传入的参数构造 BoundSql。
  • 用 JDBC 执行语句。
  • 拿到结果 ResultSet,交给 ResultSetHandler 处理。

举个例子

在底层:

  • 生成 MappedStatement,存进 Configuration。
  • 参数映射由 ParameterHandler 完成。
  • 结果封装由 ResultSetHandler 完成。

面试官会问什么?

  • MappedStatement 是干嘛的?
  • #{} 和 ${} 的区别?
  • ResultMap 是怎么实现结果映射的?

回答要点:

  • MappedStatement 是 MyBatis 执行 SQL 的核心数据结构,包含了 SQL 字符串、参数类型、返回类型等。
  • {} 是预编译,防止SQL注入;${} 是直接拼接字符串,有风险。

  • ResultMap 可以自定义属性-字段映射,解决字段与实体属性不一致问题。

第三层:基础支撑层(幕后功臣)

关键词:DataSource、Transaction、Plugin、Logging

这是最底层,但至关重要的一层。

你可能没怎么直接用过它,但没有它,MyBatis 根本跑不起来。

它负责什么?

  • 数据库连接:MyBatis 通过 DataSource 获取数据库连接。
  • 事务控制:通过 TransactionFactory 实现事务管理(JDBC / MANAGED)。
  • 插件机制:MyBatis 支持四大插件点:
    • Executor
    • StatementHandler
    • ParameterHandler
    • ResultSetHandler
  • 日志输出:支持 Log4j、SLF4J 等多种日志实现。

这一层最重要的“牛”是插件系统。MyBatis 提供了一个非常灵活的拦截机制,可以用来做性能监控、SQL记录、甚至权限过滤!

插件怎么写?

再注册到 mybatis-config.xml 中,就OK啦!

面试官会问:

  • 插件机制的实现原理?
  • MyBatis 是怎么实现事务控制的?
  • DataSource 有哪几种?可以集成Druid吗?

回答建议:

  • 插件通过 JDK 动态代理实现,对四大组件的方法进行拦截。
  • 事务通过 Transaction 接口控制,默认支持 JDBC 和 MANAGED。
  • DataSource 可自定义实现,常见的有 UNPOOLED、POOLED,集成 Druid 需要单独配置。

总结:一张图记住三层架构

来,一张图带你回顾刚才说的三层结构:

小米的面试建议

如果你在面试中遇到:

“说一下MyBatis的架构”

你可以按这个顺序回答:

“MyBatis 的功能架构可以分为三层:API 接口层、数据处理层和基础支撑层。上层负责暴露操作接口,中层是 SQL 执行和结果映射的核心,底层则负责数据库连接、事务、插件等支撑工作。这种分层使得 MyBatis 解耦清晰,扩展性好,插件机制也特别灵活。”

一口气说完这些,面试官基本都会点头,说声“可以的,很全面”。

END

现在的小李,已经知道 MyBatis 的三层架构,不仅能流利描述每层的作用,还能对 Handler、MappedStatement、Plugin、Transaction 一一道来。

他面试也不再胆怯,终于拿到了心仪公司的 offer!

而你,也可以!

我是小米,一个喜欢分享技术的31岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货!