面试知识库
进阶

MyBatis执行流程#

一句话答案#

SqlSessionFactory→SqlSession→Executor→StatementHandler→JDBC,Mapper 接口通过 JDK 动态代理绑定 SQL。

核心要点

MyBatis 的核心功能:

  1. SQL 与代码分离:SQL 写在 XML 或注解中,Java 代码只调用接口方法
  2. 动态 SQL<if>, <foreach>, <choose> 等标签,根据条件拼接 SQL
  3. 结果映射(ResultMap):将 ResultSet 自动映射为 Java 对象(支持复杂嵌套关系)
  4. 一级缓存(SqlSession)/ 二级缓存(Mapper)

MyBatis 的 Mapper 接口代理实现:

  • @Mapper 接口没有实现类,由 MyBatis 通过 JDK 动态代理生成代理对象
  • 调用 Mapper 方法 → 代理对象拦截 → 根据方法名和 namespace 找到对应 SQL → 执行

MyBatis 的插件机制(Interceptor/切面):

MyBatis 允许在以下四个核心对象的指定方法上插入拦截器:

Executor        → update/query/commit/rollback(执行层)
StatementHandler → prepare/query/update(SQL 处理层)
ParameterHandler → setParameters(参数处理)
ResultSetHandler → handleResultSets(结果处理)
java

典型插件应用:

// 分页插件(PageHelper/MyBatis-Plus):拦截 Executor.query(),在 SQL 后追加 LIMIT
// 数据权限:拦截 query,在 WHERE 子句追加权限过滤条件(如 AND dept_id = :deptId)
// SQL 日志打印:拦截 StatementHandler,打印完整的带参数 SQL
// 数据脱敏:拦截 ResultSetHandler,对返回结果的敏感字段做脱敏处理

@Intercepts({@Signature(type=Executor.class, method="query", args={...})})
public class MyPlugin implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 前置处理
        Object result = invocation.proceed();  // 执行原方法
        // 后置处理
        return result;
    }
}
java
面试回答(2分钟版)

MyBatis 的执行流程是一条清晰的调用链。首先应用启动时通过 SqlSessionFactoryBuilder 解析 mybatis-config.xml 和 Mapper XML 构建 SqlSessionFactory,它是全局唯一的工厂。每次数据库操作时从 SqlSessionFactory 获取一个 SqlSession,SqlSession 是对一次数据库会话的封装。我们写的 Mapper 接口没有实现类,MyBatis 通过 JDK 动态代理为每个 Mapper 接口生成代理对象,调用接口方法时代理对象根据方法全限定名找到对应的 MappedStatement(XML 中的 SQL 定义)。接着 SqlSession 把执行委托给 Executor,Executor 负责缓存查询和事务管理,它再调用 StatementHandler 创建 JDBC Statement,由 ParameterHandler 设置参数,最终通过 JDBC 执行 SQL。查询结果由 ResultSetHandler 根据 ResultMap 配置映射为 Java 对象返回。MyBatis 还提供了插件机制,可以在 Executor、StatementHandler、ParameterHandler、ResultSetHandler 四个核心对象上做拦截增强,比如分页插件 PageHelper 就是拦截 Executor 的 query 方法追加 LIMIT 子句。

追问与易错

追问方向:

  • “Mapper 没有实现类怎么执行?”→ MyBatis 通过 JDK 动态代理为每个 Mapper 接口生成代理对象(MapperProxy),调用方法时根据接口全限定名 + 方法名匹配 XML 中的 MappedStatement 执行 SQL
  • “插件机制能拦截什么?”→ 可拦截四大核心对象:Executor(执行层)、StatementHandler(SQL 处理)、ParameterHandler(参数设置)、ResultSetHandler(结果映射),典型应用如 PageHelper 分页、数据权限过滤
  • “参数怎么设置进去的?”→ ParameterHandler 负责将 Java 参数设置到 PreparedStatement 中,通过 TypeHandler 做类型转换,将 #{} 占位符对应的参数值调用 setXxx 方法绑定到 JDBC 语句

易错点:

  • ❌ Mapper 有隐藏实现类——纯代理没有
  • ❌ 混淆 SqlSession 和 Connection