外观
一句话答案
SqlSessionFactory→SqlSession→Executor→StatementHandler→JDBC,Mapper 接口通过 JDK 动态代理绑定 SQL。
核心要点
MyBatis 的核心功能:
- SQL 与代码分离:SQL 写在 XML 或注解中,Java 代码只调用接口方法
- 动态 SQL:
<if>,<foreach>,<choose>等标签,根据条件拼接 SQL - 结果映射(ResultMap):将 ResultSet 自动映射为 Java 对象(支持复杂嵌套关系)
- 一级缓存(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"自动干活。