Skip to content
进阶

一句话答案

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 允许在以下四个核心对象的指定方法上插入拦截器:

java
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;
    }
}
追问与易错

追问方向:

  • Mapper 没有实现类怎么执行?
  • 插件机制能拦截什么?
  • 参数怎么设置进去的?

易错点:

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

💡 记忆锚点

MyBatis执行链 = 流水线:SqlSessionFactory(工厂) -> SqlSession(车间) -> Executor(工头) -> StatementHandler(操作工) -> JDBC(机器)。Mapper接口没有实现类,靠JDK动态代理"按方法名找SQL"自动干活。