跳过正文
MyBatis工作原理笔记
  1. 📝 文章/

MyBatis工作原理笔记

·7314 字·15 分钟
Sloth
作者
Sloth
Java后端开发|全栈工程师
目录

1. MyBatis 架构概述
#

1.1 什么是 MyBatis
#

MyBatis 是一款优秀的半自动化 ORM 框架,它避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的工作。

1.2 整体架构图
#

flowchart TB
    subgraph Application["应用层"]
        A[Mapper Interface] 
        B[SqlSession API]
    end
    
    subgraph Interface["接口层"]
        C[SqlSession]
    end
    
    subgraph Core["核心处理层"]
        D[Configuration]
        E[MappedStatement]
        F[Executor]
        G[StatementHandler]
        H[ParameterHandler]
        I[ResultSetHandler]
    end
    
    subgraph Foundation["基础支撑层"]
        J[DataSource]
        K[Transaction]
        L[Cache]
        M[Logging]
        N[TypeHandler]
        O[Reflection]
    end
    
    subgraph DB["数据库层"]
        P[(Database)]
    end
    
    A --> C
    B --> C
    C --> F
    D --> F
    E --> F
    F --> G
    G --> H
    G --> I
    H --> N
    I --> N
    G --> P
    F --> L
    F --> K
    K --> J
    J --> P

1.3 三层架构说明
#

flowchart LR
    subgraph Layer1["接口层"]
        direction TB
        S1[SqlSession]
        S2["提供API给应用程序调用"]
    end
    
    subgraph Layer2["核心处理层"]
        direction TB
        C1[配置解析]
        C2[参数映射]
        C3[SQL解析]
        C4[SQL执行]
        C5[结果映射]
    end
    
    subgraph Layer3["基础支撑层"]
        direction TB
        B1[连接管理]
        B2[事务管理]
        B3[缓存机制]
        B4[类型转换]
    end
    
    Layer1 --> Layer2 --> Layer3

2. 核心组件详解
#

2.1 核心组件关系图
#

flowchart TB
    subgraph Config["Configuration 全局配置"]
        C1[Environment<br/>数据源/事务管理器]
        C2[MapperRegistry<br/>Mapper注册表]
        C3[MappedStatements<br/>SQL映射]
        C4[TypeHandlerRegistry<br/>类型处理器]
        C5[TypeAliasRegistry<br/>类型别名]
        C6[InterceptorChain<br/>拦截器链]
        C7[Cache<br/>缓存配置]
    end
    
    Config --> SSF[SqlSessionFactory<br/>创建SqlSession的工厂]
    SSF --> SS[SqlSession<br/>执行SQL/获取Mapper/管理事务]
    
    SS --> E[Executor<br/>执行器]
    SS --> MP[Mapper Proxy<br/>Mapper代理]
    SS --> TX[Transaction<br/>事务]
    
    E --> SH[StatementHandler]
    SH --> PH[ParameterHandler]
    SH --> RH[ResultSetHandler]

2.2 核心组件类图
#

classDiagram
    class SqlSessionFactoryBuilder {
        +build(InputStream) SqlSessionFactory
        +build(Configuration) SqlSessionFactory
    }
    
    class SqlSessionFactory {
        <<interface>>
        +openSession() SqlSession
        +getConfiguration() Configuration
    }
    
    class DefaultSqlSessionFactory {
        -Configuration configuration
        +openSession() SqlSession
    }
    
    class SqlSession {
        <<interface>>
        +selectOne(String, Object) T
        +selectList(String, Object) List
        +insert(String, Object) int
        +update(String, Object) int
        +delete(String, Object) int
        +getMapper(Class) T
        +commit() void
        +rollback() void
        +close() void
    }
    
    class DefaultSqlSession {
        -Configuration configuration
        -Executor executor
    }
    
    class Configuration {
        -Environment environment
        -MapperRegistry mapperRegistry
        -Map~String, MappedStatement~ mappedStatements
        -TypeHandlerRegistry typeHandlerRegistry
        -InterceptorChain interceptorChain
    }
    
    SqlSessionFactoryBuilder ..> SqlSessionFactory : creates
    SqlSessionFactory <|.. DefaultSqlSessionFactory
    SqlSession <|.. DefaultSqlSession
    DefaultSqlSessionFactory --> Configuration
    DefaultSqlSession --> Configuration
    DefaultSqlSession --> Executor

2.3 Executor 继承体系
#

classDiagram
    class Executor {
        <<interface>>
        +update(MappedStatement, Object) int
        +query(MappedStatement, Object, RowBounds, ResultHandler) List
        +commit(boolean) void
        +rollback(boolean) void
        +createCacheKey() CacheKey
    }
    
    class BaseExecutor {
        <<abstract>>
        #Transaction transaction
        #PerpetualCache localCache
        #doUpdate()* int
        #doQuery()* List
    }
    
    class SimpleExecutor {
        +doQuery() List
        +doUpdate() int
    }
    
    class ReuseExecutor {
        -Map~String, Statement~ statementMap
        +doQuery() List
    }
    
    class BatchExecutor {
        -List~Statement~ statementList
        +doUpdate() int
    }
    
    class CachingExecutor {
        -Executor delegate
        -TransactionalCacheManager tcm
        +query() List
    }
    
    Executor <|.. BaseExecutor
    Executor <|.. CachingExecutor
    BaseExecutor <|-- SimpleExecutor
    BaseExecutor <|-- ReuseExecutor
    BaseExecutor <|-- BatchExecutor
    CachingExecutor o-- Executor : 装饰

3. 初始化流程
#

3.1 初始化时序图
#

sequenceDiagram
    autonumber
    participant Client as 客户端
    participant Builder as SqlSessionFactoryBuilder
    participant XMLConfig as XMLConfigBuilder
    participant Config as Configuration
    participant XMLMapper as XMLMapperBuilder
    
    Client->>Builder: build(inputStream)
    Builder->>XMLConfig: new XMLConfigBuilder(inputStream)
    XMLConfig->>Config: new Configuration()
    Builder->>XMLConfig: parse()
    
    activate XMLConfig
    XMLConfig->>Config: 解析 properties
    XMLConfig->>Config: 解析 settings
    XMLConfig->>Config: 解析 typeAliases
    XMLConfig->>Config: 解析 plugins
    XMLConfig->>Config: 解析 environments
    XMLConfig->>Config: 解析 typeHandlers
    
    XMLConfig->>XMLMapper: 解析 mappers
    XMLMapper->>Config: 注册 MappedStatement
    XMLMapper->>Config: 注册 ResultMap
    XMLMapper-->>XMLConfig: 完成
    deactivate XMLConfig
    
    XMLConfig-->>Builder: 返回 Configuration
    Builder->>Builder: new DefaultSqlSessionFactory(config)
    Builder-->>Client: 返回 SqlSessionFactory

3.2 配置文件解析流程
#

flowchart TB
    A[mybatis-config.xml] --> B[XMLConfigBuilder]
    
    B --> C{解析各节点}
    
    C --> D[properties<br/>外部属性]
    C --> E[settings<br/>全局设置]
    C --> F[typeAliases<br/>类型别名]
    C --> G[plugins<br/>插件]
    C --> H[environments<br/>环境配置]
    C --> I[typeHandlers<br/>类型处理器]
    C --> J[mappers<br/>映射器]
    
    J --> K{mapper配置方式}
    K --> L[resource<br/>XML文件路径]
    K --> M[class<br/>Mapper接口]
    K --> N[package<br/>包扫描]
    
    L --> O[XMLMapperBuilder]
    M --> P[MapperAnnotationBuilder]
    N --> P
    
    O --> Q[解析Mapper.xml]
    P --> R[解析注解]
    
    Q --> S[MappedStatement]
    R --> S
    
    S --> T[Configuration]

3.3 MappedStatement 结构
#

classDiagram
    class MappedStatement {
        -String id
        -SqlCommandType sqlCommandType
        -SqlSource sqlSource
        -ParameterMap parameterMap
        -List~ResultMap~ resultMaps
        -Cache cache
        -boolean useCache
        -boolean flushCacheRequired
        -StatementType statementType
        -Integer timeout
        -Integer fetchSize
    }
    
    class SqlSource {
        <<interface>>
        +getBoundSql(Object) BoundSql
    }
    
    class StaticSqlSource {
        -String sql
    }
    
    class DynamicSqlSource {
        -SqlNode rootSqlNode
    }
    
    class RawSqlSource {
        -SqlSource sqlSource
    }
    
    class BoundSql {
        -String sql
        -List~ParameterMapping~ parameterMappings
        -Object parameterObject
        -Map additionalParameters
    }
    
    MappedStatement --> SqlSource
    SqlSource <|.. StaticSqlSource
    SqlSource <|.. DynamicSqlSource
    SqlSource <|.. RawSqlSource
    SqlSource ..> BoundSql : creates

3.4 初始化源码解析
#

/**
 * SqlSessionFactoryBuilder - 入口类
 */
public class SqlSessionFactoryBuilder {
    
    public SqlSessionFactory build(InputStream inputStream) {
        return build(inputStream, null, null);
    }
    
    public SqlSessionFactory build(InputStream inputStream, 
                                   String environment, 
                                   Properties properties) {
        try {
            // 1. 创建 XML 配置解析器
            XMLConfigBuilder parser = new XMLConfigBuilder(
                inputStream, environment, properties);
            
            // 2. 解析配置文件,返回 Configuration 对象
            Configuration config = parser.parse();
            
            // 3. 创建 DefaultSqlSessionFactory
            return build(config);
        } catch (Exception e) {
            throw ExceptionFactory.wrapException("Error building SqlSession.", e);
        }
    }
    
    public SqlSessionFactory build(Configuration config) {
        return new DefaultSqlSessionFactory(config);
    }
}

/**
 * XMLConfigBuilder - 解析 mybatis-config.xml
 */
public class XMLConfigBuilder extends BaseBuilder {
    
    public Configuration parse() {
        if (parsed) {
            throw new BuilderException("Each XMLConfigBuilder can only be used once.");
        }
        parsed = true;
        
        // 从根节点 <configuration> 开始解析
        parseConfiguration(parser.evalNode("/configuration"));
        
        return configuration;
    }
    
    private void parseConfiguration(XNode root) {
        try {
            // 按顺序解析各个子节点
            propertiesElement(root.evalNode("properties"));
            Properties settings = settingsAsProperties(root.evalNode("settings"));
            typeAliasesElement(root.evalNode("typeAliases"));
            pluginElement(root.evalNode("plugins"));
            objectFactoryElement(root.evalNode("objectFactory"));
            settingsElement(settings);
            environmentsElement(root.evalNode("environments"));
            typeHandlerElement(root.evalNode("typeHandlers"));
            mapperElement(root.evalNode("mappers"));  // ⭐ 解析 Mapper
        } catch (Exception e) {
            throw new BuilderException("Error parsing SQL Mapper Configuration.", e);
        }
    }
}

4. SQL 执行流程
#

4.1 SQL 执行时序图
#

sequenceDiagram
    autonumber
    participant Client as 客户端
    participant SS as SqlSession
    participant E as Executor
    participant SH as StatementHandler
    participant PH as ParameterHandler
    participant TH as TypeHandler
    participant RH as ResultSetHandler
    participant DB as Database
    
    Client->>SS: selectList(statementId, parameter)
    SS->>SS: getMappedStatement(id)
    SS->>E: query(ms, parameter, rowBounds, resultHandler)
    
    alt 缓存命中
        E->>E: 查询一级缓存
        E-->>SS: 返回缓存结果
    else 缓存未命中
        E->>E: 创建 CacheKey
        E->>SH: prepare(connection, timeout)
        SH->>DB: prepareStatement(sql)
        DB-->>SH: PreparedStatement
        
        E->>SH: parameterize(statement)
        SH->>PH: setParameters(ps)
        
        loop 遍历参数映射
            PH->>TH: setParameter(ps, i, value, jdbcType)
            TH->>DB: ps.setXxx(i, value)
        end
        
        E->>SH: query(statement, resultHandler)
        SH->>DB: ps.execute()
        DB-->>SH: ResultSet
        
        SH->>RH: handleResultSets(ps)
        
        loop 遍历结果集
            RH->>TH: getResult(rs, columnName)
            TH-->>RH: Java对象
        end
        
        RH-->>SH: List<Object>
        SH-->>E: List<Object>
        
        E->>E: 放入一级缓存
    end
    
    E-->>SS: List<Object>
    SS-->>Client: List<Object>

4.2 执行器工作流程
#

flowchart TB
    A[SqlSession.selectList] --> B[获取 MappedStatement]
    B --> C[Executor.query]
    
    C --> D{二级缓存开启?}
    D -->|是| E[CachingExecutor]
    D -->|否| F[BaseExecutor]
    
    E --> G{二级缓存命中?}
    G -->|是| H[返回缓存结果]
    G -->|否| F
    
    F --> I{一级缓存命中?}
    I -->|是| J[返回缓存结果]
    I -->|否| K[queryFromDatabase]
    
    K --> L[doQuery - 由子类实现]
    
    L --> M{Executor类型}
    M -->|SimpleExecutor| N[每次创建新Statement]
    M -->|ReuseExecutor| O[复用Statement]
    M -->|BatchExecutor| P[批量执行]
    
    N --> Q[StatementHandler.prepare]
    O --> Q
    P --> Q
    
    Q --> R[ParameterHandler.setParameters]
    R --> S[StatementHandler.query]
    S --> T[ResultSetHandler.handleResultSets]
    T --> U[返回结果并缓存]

4.3 四大处理器协作
#

flowchart LR
    subgraph Executor["Executor 执行器"]
        E1[管理事务]
        E2[管理缓存]
        E3[创建Handler]
    end
    
    subgraph StatementHandler["StatementHandler"]
        S1[prepare<br/>创建Statement]
        S2[parameterize<br/>委托参数处理]
        S3[query/update<br/>执行SQL]
    end
    
    subgraph ParameterHandler["ParameterHandler"]
        P1[setParameters<br/>设置SQL参数]
    end
    
    subgraph ResultSetHandler["ResultSetHandler"]
        R1[handleResultSets<br/>处理结果集]
        R2[映射到Java对象]
    end
    
    subgraph TypeHandler["TypeHandler"]
        T1[setParameter<br/>Java→JDBC]
        T2[getResult<br/>JDBC→Java]
    end
    
    Executor --> StatementHandler
    StatementHandler --> ParameterHandler
    StatementHandler --> ResultSetHandler
    ParameterHandler --> TypeHandler
    ResultSetHandler --> TypeHandler

4.4 DefaultSqlSession 核心代码
#

/**
 * DefaultSqlSession - SQL 执行入口
 */
public class DefaultSqlSession implements SqlSession {
    
    private final Configuration configuration;
    private final Executor executor;
    
    @Override
    public <E> List<E> selectList(String statement, Object parameter) {
        return this.selectList(statement, parameter, RowBounds.DEFAULT);
    }
    
    @Override
    public <E> List<E> selectList(String statement, Object parameter, 
                                  RowBounds rowBounds) {
        try {
            // 1. 获取 MappedStatement
            MappedStatement ms = configuration.getMappedStatement(statement);
            
            // 2. 调用 Executor 执行查询
            return executor.query(ms, wrapCollection(parameter), 
                                  rowBounds, Executor.NO_RESULT_HANDLER);
        } catch (Exception e) {
            throw ExceptionFactory.wrapException("Error querying database.", e);
        }
    }
    
    @Override
    public int update(String statement, Object parameter) {
        try {
            dirty = true;
            MappedStatement ms = configuration.getMappedStatement(statement);
            return executor.update(ms, wrapCollection(parameter));
        } catch (Exception e) {
            throw ExceptionFactory.wrapException("Error updating database.", e);
        }
    }
    
    @Override
    public <T> T getMapper(Class<T> type) {
        return configuration.getMapper(type, this);
    }
}

4.5 SimpleExecutor 执行逻辑
#

/**
 * SimpleExecutor - 简单执行器
 */
public class SimpleExecutor extends BaseExecutor {
    
    @Override
    public <E> List<E> doQuery(MappedStatement ms, Object parameter,
                               RowBounds rowBounds, ResultHandler resultHandler,
                               BoundSql boundSql) throws SQLException {
        Statement stmt = null;
        try {
            Configuration configuration = ms.getConfiguration();
            
            // 1. 创建 StatementHandler
            StatementHandler handler = configuration.newStatementHandler(
                wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
            
            // 2. 预处理 Statement
            stmt = prepareStatement(handler, ms.getStatementLog());
            
            // 3. 执行查询
            return handler.query(stmt, resultHandler);
            
        } finally {
            closeStatement(stmt);
        }
    }
    
    private Statement prepareStatement(StatementHandler handler, Log statementLog)
            throws SQLException {
        Statement stmt;
        
        // 1. 获取数据库连接
        Connection connection = getConnection(statementLog);
        
        // 2. 创建 Statement
        stmt = handler.prepare(connection, transaction.getTimeout());
        
        // 3. 设置参数
        handler.parameterize(stmt);
        
        return stmt;
    }
}

5. 动态代理机制
#

5.1 Mapper 代理原理图
#

flowchart TB
    subgraph Application["应用层"]
        A[UserMapper<br/>接口定义]
        B["mapper.selectById(1)"]
    end
    
    subgraph Proxy["代理层"]
        C[MapperProxyFactory<br/>创建代理]
        D[MapperProxy<br/>InvocationHandler]
        E[MapperMethod<br/>方法执行器]
    end
    
    subgraph SqlSession["SqlSession层"]
        F[selectOne]
        G[selectList]
        H[insert]
        I[update]
        J[delete]
    end
    
    A -->|getMapper| C
    C -->|Proxy.newProxyInstance| D
    B -->|invoke| D
    D -->|cachedInvoker| E
    
    E -->|SELECT| F
    E -->|SELECT returnMany| G
    E -->|INSERT| H
    E -->|UPDATE| I
    E -->|DELETE| J

5.2 动态代理时序图
#

sequenceDiagram
    autonumber
    participant Client as 客户端
    participant SS as SqlSession
    participant MR as MapperRegistry
    participant MPF as MapperProxyFactory
    participant MP as MapperProxy
    participant MM as MapperMethod
    
    Client->>SS: getMapper(UserMapper.class)
    SS->>MR: getMapper(type, sqlSession)
    MR->>MPF: newInstance(sqlSession)
    
    Note over MPF: 创建 MapperProxy
    MPF->>MP: new MapperProxy(sqlSession, mapperInterface, methodCache)
    
    Note over MPF: JDK动态代理
    MPF->>MPF: Proxy.newProxyInstance(classLoader, interfaces, mapperProxy)
    MPF-->>Client: 返回代理对象
    
    Client->>MP: selectById(1)
    MP->>MP: invoke(proxy, method, args)
    
    alt Object方法
        MP->>MP: method.invoke(this, args)
    else 接口默认方法
        MP->>MP: invokeDefaultMethod()
    else 普通方法
        MP->>MP: cachedInvoker(method)
        MP->>MM: new MapperMethod(interface, method, config)
        MP->>MM: execute(sqlSession, args)
        
        MM->>MM: 判断SQL类型
        MM->>SS: selectOne/selectList/insert/update/delete
        SS-->>MM: 结果
        MM-->>MP: 结果
    end
    
    MP-->>Client: 结果

5.3 MapperProxy 类结构
#

classDiagram
    class MapperProxy~T~ {
        -SqlSession sqlSession
        -Class~T~ mapperInterface
        -Map~Method, MapperMethodInvoker~ methodCache
        +invoke(Object proxy, Method method, Object[] args) Object
        -cachedInvoker(Method method) MapperMethodInvoker
    }
    
    class MapperProxyFactory~T~ {
        -Class~T~ mapperInterface
        -Map~Method, MapperMethodInvoker~ methodCache
        +newInstance(SqlSession sqlSession) T
        #newInstance(MapperProxy~T~ mapperProxy) T
    }
    
    class MapperMethod {
        -SqlCommand command
        -MethodSignature method
        +execute(SqlSession sqlSession, Object[] args) Object
    }
    
    class SqlCommand {
        -String name
        -SqlCommandType type
    }
    
    class MethodSignature {
        -boolean returnsMany
        -boolean returnsMap
        -boolean returnsVoid
        -Class~?~ returnType
        -ParamNameResolver paramNameResolver
    }
    
    class MapperMethodInvoker {
        <<interface>>
        +invoke(Object, Method, Object[], SqlSession) Object
    }
    
    class PlainMethodInvoker {
        -MapperMethod mapperMethod
    }
    
    MapperProxyFactory ..> MapperProxy : creates
    MapperProxy ..|> InvocationHandler
    MapperProxy --> MapperMethodInvoker
    MapperMethodInvoker <|.. PlainMethodInvoker
    PlainMethodInvoker --> MapperMethod
    MapperMethod --> SqlCommand
    MapperMethod --> MethodSignature

5.4 MapperProxy 源码解析
#

/**
 * MapperProxy - Mapper 接口的代理处理器
 */
public class MapperProxy<T> implements InvocationHandler, Serializable {
    
    private final SqlSession sqlSession;
    private final Class<T> mapperInterface;
    private final Map<Method, MapperMethodInvoker> methodCache;
    
    /**
     * 代理方法调用入口
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) 
            throws Throwable {
        try {
            // 1. 如果是 Object 类的方法,直接调用
            if (Object.class.equals(method.getDeclaringClass())) {
                return method.invoke(this, args);
            }
            
            // 2. 如果是接口的默认方法(Java 8+)
            if (method.isDefault()) {
                return invokeDefaultMethod(proxy, method, args);
            }
            
        } catch (Throwable t) {
            throw ExceptionUtil.unwrapThrowable(t);
        }
        
        // 3. 获取或创建 MapperMethodInvoker,然后执行
        final MapperMethodInvoker invoker = cachedInvoker(method);
        return invoker.invoke(proxy, method, args, sqlSession);
    }
    
    /**
     * 缓存方法调用器
     */
    private MapperMethodInvoker cachedInvoker(Method method) throws Throwable {
        return methodCache.computeIfAbsent(method, m -> {
            if (m.isDefault()) {
                return new DefaultMethodInvoker(getMethodHandle(method));
            } else {
                return new PlainMethodInvoker(
                    new MapperMethod(mapperInterface, method, 
                                    sqlSession.getConfiguration()));
            }
        });
    }
}

/**
 * MapperMethod - 封装方法执行逻辑
 */
public class MapperMethod {
    
    private final SqlCommand command;
    private final MethodSignature method;
    
    /**
     * 执行方法
     */
    public Object execute(SqlSession sqlSession, Object[] args) {
        Object result;
        
        switch (command.getType()) {
            case INSERT: {
                Object param = method.convertArgsToSqlCommandParam(args);
                result = rowCountResult(sqlSession.insert(command.getName(), param));
                break;
            }
            case UPDATE: {
                Object param = method.convertArgsToSqlCommandParam(args);
                result = rowCountResult(sqlSession.update(command.getName(), param));
                break;
            }
            case DELETE: {
                Object param = method.convertArgsToSqlCommandParam(args);
                result = rowCountResult(sqlSession.delete(command.getName(), param));
                break;
            }
            case SELECT:
                if (method.returnsVoid() && method.hasResultHandler()) {
                    executeWithResultHandler(sqlSession, args);
                    result = null;
                } else if (method.returnsMany()) {
                    result = executeForMany(sqlSession, args);
                } else if (method.returnsMap()) {
                    result = executeForMap(sqlSession, args);
                } else {
                    Object param = method.convertArgsToSqlCommandParam(args);
                    result = sqlSession.selectOne(command.getName(), param);
                }
                break;
            default:
                throw new BindingException("Unknown execution method for: " 
                    + command.getName());
        }
        
        return result;
    }
}

6. 缓存机制
#

6.1 两级缓存架构
#

flowchart TB
    subgraph Session1["SqlSession 1"]
        L1A[一级缓存<br/>PerpetualCache]
    end
    
    subgraph Session2["SqlSession 2"]
        L1B[一级缓存<br/>PerpetualCache]
    end
    
    subgraph Session3["SqlSession 3"]
        L1C[一级缓存<br/>PerpetualCache]
    end
    
    subgraph L2Cache["二级缓存 (Mapper Namespace级别)"]
        subgraph NS1["UserMapper Namespace"]
            C1[SynchronizedCache]
            C2[LoggingCache]
            C3[SerializedCache]
            C4[LruCache]
            C5[PerpetualCache]
            C1 --> C2 --> C3 --> C4 --> C5
        end
        
        subgraph NS2["OrderMapper Namespace"]
            D1[SynchronizedCache]
            D2[LoggingCache]
            D3[PerpetualCache]
            D1 --> D2 --> D3
        end
    end
    
    Session1 --> L2Cache
    Session2 --> L2Cache
    Session3 --> L2Cache
    
    L2Cache --> DB[(Database)]
    
    style L1A fill:#e1f5fe
    style L1B fill:#e1f5fe
    style L1C fill:#e1f5fe
    style L2Cache fill:#fff3e0

6.2 缓存查询流程
#

flowchart TB
    A[查询请求] --> B{二级缓存开启?}
    
    B -->|是| C[CachingExecutor]
    B -->|否| D[BaseExecutor]
    
    C --> E{二级缓存命中?}
    E -->|是| F[返回二级缓存结果]
    E -->|否| D
    
    D --> G{一级缓存命中?}
    G -->|是| H[返回一级缓存结果]
    G -->|否| I[查询数据库]
    
    I --> J[结果放入一级缓存]
    J --> K{二级缓存开启?}
    
    K -->|是| L[暂存到TransactionalCache]
    K -->|否| M[返回结果]
    
    L --> N{事务提交?}
    N -->|是| O[刷新到二级缓存]
    N -->|否| P[事务回滚清空]
    
    O --> M
    P --> M

6.3 缓存装饰器模式
#

classDiagram
    class Cache {
        <<interface>>
        +getId() String
        +putObject(Object key, Object value) void
        +getObject(Object key) Object
        +removeObject(Object key) Object
        +clear() void
        +getSize() int
    }
    
    class PerpetualCache {
        -String id
        -Map~Object, Object~ cache
        +putObject() void
        +getObject() Object
    }
    
    class LruCache {
        -Cache delegate
        -Map keyMap
        -Object eldestKey
    }
    
    class FifoCache {
        -Cache delegate
        -Deque~Object~ keyList
    }
    
    class SoftCache {
        -Cache delegate
        -Deque~Object~ hardLinksToAvoidGC
    }
    
    class WeakCache {
        -Cache delegate
    }
    
    class SynchronizedCache {
        -Cache delegate
    }
    
    class LoggingCache {
        -Cache delegate
        -int requests
        -int hits
    }
    
    class SerializedCache {
        -Cache delegate
    }
    
    class ScheduledCache {
        -Cache delegate
        -long clearInterval
    }
    
    Cache <|.. PerpetualCache
    Cache <|.. LruCache
    Cache <|.. FifoCache
    Cache <|.. SoftCache
    Cache <|.. WeakCache
    Cache <|.. SynchronizedCache
    Cache <|.. LoggingCache
    Cache <|.. SerializedCache
    Cache <|.. ScheduledCache
    
    LruCache o-- Cache
    FifoCache o-- Cache
    SoftCache o-- Cache
    WeakCache o-- Cache
    SynchronizedCache o-- Cache
    LoggingCache o-- Cache
    SerializedCache o-- Cache
    ScheduledCache o-- Cache

6.4 一级缓存实现
#

/**
 * 一级缓存 - BaseExecutor 中的实现
 */
public abstract class BaseExecutor implements Executor {
    
    // 一级缓存
    protected PerpetualCache localCache;
    
    @Override
    public <E> List<E> query(MappedStatement ms, Object parameter, 
                             RowBounds rowBounds, ResultHandler resultHandler,
                             CacheKey key, BoundSql boundSql) throws SQLException {
        
        // 如果配置了 flushCache=true,清空缓存
        if (queryStack == 0 && ms.isFlushCacheRequired()) {
            clearLocalCache();
        }
        
        List<E> list;
        try {
            queryStack++;
            
            // 从一级缓存获取结果
            list = resultHandler == null 
                   ? (List<E>) localCache.getObject(key) 
                   : null;
                   
            if (list != null) {
                // 缓存命中
                handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
            } else {
                // 缓存未命中,查询数据库
                list = queryFromDatabase(ms, parameter, rowBounds, 
                                         resultHandler, key, boundSql);
            }
        } finally {
            queryStack--;
        }
        
        return list;
    }
    
    /**
     * 创建缓存 Key
     */
    @Override
    public CacheKey createCacheKey(MappedStatement ms, Object parameterObject,
                                   RowBounds rowBounds, BoundSql boundSql) {
        CacheKey cacheKey = new CacheKey();
        
        // 缓存 Key 由以下几部分组成
        cacheKey.update(ms.getId());                // Statement ID
        cacheKey.update(rowBounds.getOffset());     // 分页偏移
        cacheKey.update(rowBounds.getLimit());      // 分页大小
        cacheKey.update(boundSql.getSql());         // SQL 语句
        
        // 参数值
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        for (ParameterMapping pm : parameterMappings) {
            if (pm.getMode() != ParameterMode.OUT) {
                Object value = /* 获取参数值 */;
                cacheKey.update(value);
            }
        }
        
        return cacheKey;
    }
}

6.5 二级缓存实现
#

/**
 * 二级缓存 - CachingExecutor (装饰器模式)
 */
public class CachingExecutor implements Executor {
    
    private final Executor delegate;              // 被装饰的执行器
    private final TransactionalCacheManager tcm = new TransactionalCacheManager();
    
    @Override
    public <E> List<E> query(MappedStatement ms, Object parameterObject, 
                             RowBounds rowBounds, ResultHandler resultHandler,
                             CacheKey key, BoundSql boundSql) throws SQLException {
        
        // 获取 MappedStatement 对应的二级缓存
        Cache cache = ms.getCache();
        
        if (cache != null) {
            flushCacheIfRequired(ms);
            
            if (ms.isUseCache() && resultHandler == null) {
                // 从二级缓存获取结果
                List<E> list = (List<E>) tcm.getObject(cache, key);
                
                if (list == null) {
                    // 二级缓存未命中,查询一级缓存/数据库
                    list = delegate.query(ms, parameterObject, rowBounds, 
                                          resultHandler, key, boundSql);
                    
                    // 将结果放入二级缓存(暂存)
                    tcm.putObject(cache, key, list);
                }
                
                return list;
            }
        }
        
        return delegate.query(ms, parameterObject, rowBounds, 
                             resultHandler, key, boundSql);
    }
    
    @Override
    public void commit(boolean required) throws SQLException {
        delegate.commit(required);
        tcm.commit();  // 提交时才真正写入二级缓存
    }
    
    @Override
    public void rollback(boolean required) throws SQLException {
        try {
            delegate.rollback(required);
        } finally {
            if (required) {
                tcm.rollback();  // 回滚时清空暂存区
            }
        }
    }
}

6.6 缓存配置示例
#

<!-- 开启二级缓存 -->
<mapper namespace="com.example.mapper.UserMapper">
    
    <!-- 配置二级缓存 -->
    <cache 
        eviction="LRU"           
        flushInterval="60000"    
        size="1024"              
        readOnly="false"/>       
    
    <!-- 
        eviction: 淘汰策略 (LRU/FIFO/SOFT/WEAK)
        flushInterval: 刷新间隔(毫秒)
        size: 缓存数量
        readOnly: 只读(true返回相同实例,false返回拷贝)
    -->
    
    <select id="selectById" resultType="User" useCache="true">
        SELECT * FROM user WHERE id = #{id}
    </select>
    
    <update id="updateById" flushCache="true">
        UPDATE user SET name = #{name} WHERE id = #{id}
    </update>
    
</mapper>

7. 插件机制
#

7.1 插件原理
#

flowchart TB
    subgraph Interceptable["可拦截的四大对象"]
        E[Executor<br/>执行器]
        SH[StatementHandler<br/>语句处理器]
        PH[ParameterHandler<br/>参数处理器]
        RH[ResultSetHandler<br/>结果集处理器]
    end
    
    subgraph InterceptMethods["可拦截方法"]
        E1[update, query, commit<br/>rollback, flushStatements...]
        SH1[prepare, parameterize<br/>batch, update, query]
        PH1[getParameterObject<br/>setParameters]
        RH1[handleResultSets<br/>handleOutputParameters]
    end
    
    E --- E1
    SH --- SH1
    PH --- PH1
    RH --- RH1
    
    subgraph Plugin["插件机制"]
        P1[Interceptor 接口]
        P2[Plugin 代理工具]
        P3[InterceptorChain 责任链]
    end
    
    Plugin --> Interceptable

7.2 插件执行流程
#

sequenceDiagram
    autonumber
    participant Config as Configuration
    participant Chain as InterceptorChain
    participant Plugin as Plugin
    participant Interceptor as 自定义Interceptor
    participant Target as 目标对象
    
    Config->>Config: newExecutor()
    Config->>Chain: pluginAll(executor)
    
    loop 遍历所有拦截器
        Chain->>Interceptor: plugin(target)
        Interceptor->>Plugin: wrap(target, this)
        
        Plugin->>Plugin: 解析@Intercepts注解
        Plugin->>Plugin: 获取签名方法
        
        alt 需要代理
            Plugin->>Plugin: Proxy.newProxyInstance()
            Plugin-->>Interceptor: 代理对象
        else 不需要代理
            Plugin-->>Interceptor: 原对象
        end
        
        Interceptor-->>Chain: 代理/原对象
    end
    
    Chain-->>Config: 最终代理对象
    
    Note over Config,Target: 方法调用时
    
    Config->>Plugin: invoke(proxy, method, args)
    
    alt 方法需要拦截
        Plugin->>Interceptor: intercept(Invocation)
        Interceptor->>Interceptor: 前置处理
        Interceptor->>Target: invocation.proceed()
        Target-->>Interceptor: 结果
        Interceptor->>Interceptor: 后置处理
        Interceptor-->>Plugin: 结果
    else 方法不需要拦截
        Plugin->>Target: method.invoke(target, args)
        Target-->>Plugin: 结果
    end
    
    Plugin-->>Config: 结果

7.3 插件类结构
#

classDiagram
    class Interceptor {
        <<interface>>
        +intercept(Invocation invocation) Object
        +plugin(Object target) Object
        +setProperties(Properties properties) void
    }
    
    class Plugin {
        -Object target
        -Interceptor interceptor
        -Map~Class, Set~Method~~ signatureMap
        +wrap(Object target, Interceptor interceptor)$ Object
        +invoke(Object proxy, Method method, Object[] args) Object
    }
    
    class Invocation {
        -Object target
        -Method method
        -Object[] args
        +proceed() Object
        +getTarget() Object
        +getMethod() Method
        +getArgs() Object[]
    }
    
    class InterceptorChain {
        -List~Interceptor~ interceptors
        +pluginAll(Object target) Object
        +addInterceptor(Interceptor interceptor) void
    }
    
    class Intercepts {
        <<annotation>>
        +value() Signature[]
    }
    
    class Signature {
        <<annotation>>
        +type() Class
        +method() String
        +args() Class[]
    }
    
    Interceptor ..> Plugin : 使用
    Plugin ..> Invocation : 创建
    InterceptorChain o-- Interceptor
    Interceptor ..> Intercepts : 标注
    Intercepts *-- Signature

7.4 自定义插件示例
#

/**
 * SQL 执行时间统计插件
 */
@Intercepts({
    @Signature(
        type = Executor.class, 
        method = "query",
        args = {MappedStatement.class, Object.class, 
                RowBounds.class, ResultHandler.class}
    ),
    @Signature(
        type = Executor.class, 
        method = "update",
        args = {MappedStatement.class, Object.class}
    )
})
public class SqlExecutionTimePlugin implements Interceptor {
    
    private static final Logger log = LoggerFactory.getLogger(
        SqlExecutionTimePlugin.class);
    
    private long slowSqlThreshold = 1000; // 慢 SQL 阈值(毫秒)
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 1. 获取执行信息
        MappedStatement ms = (MappedStatement) invocation.getArgs()[0];
        String sqlId = ms.getId();
        
        // 2. 记录开始时间
        long startTime = System.currentTimeMillis();
        
        try {
            // 3. 执行原方法
            return invocation.proceed();
        } finally {
            // 4. 计算执行时间
            long executionTime = System.currentTimeMillis() - startTime;
            
            // 5. 慢 SQL 告警
            if (executionTime > slowSqlThreshold) {
                log.warn("慢SQL告警 - ID: {}, 耗时: {}ms", sqlId, executionTime);
            } else {
                log.debug("SQL执行 - ID: {}, 耗时: {}ms", sqlId, executionTime);
            }
        }
    }
    
    @Override
    public Object plugin(Object target) {
        // 只代理 Executor
        if (target instanceof Executor) {
            return Plugin.wrap(target, this);
        }
        return target;
    }
    
    @Override
    public void setProperties(Properties properties) {
        String threshold = properties.getProperty("slowSqlThreshold");
        if (threshold != null) {
            this.slowSqlThreshold = Long.parseLong(threshold);
        }
    }
}

/**
 * 分页插件示例
 */
@Intercepts({
    @Signature(
        type = StatementHandler.class, 
        method = "prepare", 
        args = {Connection.class, Integer.class}
    )
})
public class PaginationPlugin implements Interceptor {
    
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        
        // 使用 MetaObject 操作对象属性
        MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
        
        // 获取原始 SQL
        String sql = (String) metaObject.getValue("delegate.boundSql.sql");
        
        // 获取参数对象
        Object parameterObject = metaObject.getValue("delegate.boundSql.parameterObject");
        
        // 判断是否需要分页
        if (parameterObject instanceof PageParam) {
            PageParam page = (PageParam) parameterObject;
            
            // 修改 SQL
            String pageSql = sql + " LIMIT " + page.getOffset() 
                           + ", " + page.getPageSize();
            
            metaObject.setValue("delegate.boundSql.sql", pageSql);
        }
        
        return invocation.proceed();
    }
}

7.5 Plugin 核心源码
#

/**
 * Plugin - 创建代理对象的工具类
 */
public class Plugin implements InvocationHandler {
    
    private final Object target;
    private final Interceptor interceptor;
    private final Map<Class<?>, Set<Method>> signatureMap;
    
    /**
     * 包装目标对象
     */
    public static Object wrap(Object target, Interceptor interceptor) {
        // 1. 获取拦截器的签名信息
        Map<Class<?>, Set<Method>> signatureMap = getSignatureMap(interceptor);
        
        // 2. 获取目标对象的类型
        Class<?> type = target.getClass();
        
        // 3. 获取目标对象需要被代理的接口
        Class<?>[] interfaces = getAllInterfaces(type, signatureMap);
        
        // 4. 如果有需要代理的接口,创建代理对象
        if (interfaces.length > 0) {
            return Proxy.newProxyInstance(
                type.getClassLoader(),
                interfaces,
                new Plugin(target, interceptor, signatureMap));
        }
        
        return target;
    }
    
    /**
     * 代理方法调用
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) 
            throws Throwable {
        try {
            // 获取当前接口的可拦截方法
            Set<Method> methods = signatureMap.get(method.getDeclaringClass());
            
            // 如果当前方法需要被拦截
            if (methods != null && methods.contains(method)) {
                // 调用拦截器的 intercept 方法
                return interceptor.intercept(new Invocation(target, method, args));
            }
            
            // 不需要拦截,直接调用原方法
            return method.invoke(target, args);
            
        } catch (Exception e) {
            throw ExceptionUtil.unwrapThrowable(e);
        }
    }
    
    /**
     * 解析 @Intercepts 注解获取签名信息
     */
    private static Map<Class<?>, Set<Method>> getSignatureMap(Interceptor interceptor) {
        Intercepts interceptsAnnotation = interceptor.getClass()
            .getAnnotation(Intercepts.class);
            
        if (interceptsAnnotation == null) {
            throw new PluginException("No @Intercepts annotation was found");
        }
        
        Signature[] sigs = interceptsAnnotation.value();
        Map<Class<?>, Set<Method>> signatureMap = new HashMap<>();
        
        for (Signature sig : sigs) {
            Set<Method> methods = signatureMap.computeIfAbsent(
                sig.type(), k -> new HashSet<>());
            
            Method method = sig.type().getMethod(sig.method(), sig.args());
            methods.add(method);
        }
        
        return signatureMap;
    }
}

8. 总结
#

8.1 MyBatis 完整执行流程
#

flowchart TB
    subgraph Init["1. 初始化阶段"]
        A1[mybatis-config.xml] --> A2[XMLConfigBuilder]
        A2 --> A3[Configuration]
        A4[Mapper.xml] --> A5[XMLMapperBuilder]
        A5 --> A6[MappedStatement]
        A6 --> A3
        A3 --> A7[SqlSessionFactory]
    end
    
    subgraph Execute["2. 执行阶段"]
        B1[调用Mapper方法] --> B2[MapperProxy<br/>JDK动态代理]
        B2 --> B3[MapperMethod]
        B3 --> B4[SqlSession<br/>selectOne/insert...]
        B4 --> B5[Executor<br/>执行器]
        
        B5 --> B6{缓存}
        B6 -->|命中| B7[返回结果]
        B6 -->|未命中| B8[StatementHandler]
        
        B8 --> B9[ParameterHandler<br/>设置参数]
        B9 --> B10[TypeHandler<br/>类型转换]
        B10 --> B11[(Database)]
        B11 --> B12[ResultSetHandler<br/>结果映射]
        B12 --> B13[TypeHandler<br/>类型转换]
        B13 --> B7
    end
    
    Init --> Execute

8.2 核心设计模式
#

mindmap
  root((MyBatis<br/>设计模式))
    创建型
      工厂模式
        SqlSessionFactory
        MapperProxyFactory
      建造者模式
        SqlSessionFactoryBuilder
        XMLConfigBuilder
      单例模式
        Configuration
        ErrorContext
    结构型
      代理模式
        MapperProxy
        Plugin
      装饰器模式
        Cache装饰器
        CachingExecutor
      组合模式
        SqlNode树
        ResultMap
    行为型
      模板方法
        BaseExecutor
        BaseTypeHandler
      策略模式
        Executor类型
        StatementHandler类型
      责任链模式
        插件机制
        InterceptorChain
      迭代器模式
        PropertyTokenizer

8.3 核心组件职责
#

组件 职责 生命周期
SqlSessionFactoryBuilder 解析配置,创建工厂 用后即弃
SqlSessionFactory 创建 SqlSession 应用级单例
SqlSession 执行SQL,获取Mapper 请求级别
Executor 管理缓存,执行SQL 请求级别
StatementHandler 操作Statement 单次执行
ParameterHandler 设置SQL参数 单次执行
ResultSetHandler 处理结果集 单次执行
TypeHandler Java/JDBC类型转换 应用级别

8.4 缓存对比
#

flowchart LR
    subgraph L1["一级缓存"]
        direction TB
        L1A[作用域: SqlSession]
        L1B[默认开启]
        L1C[无法关闭]
        L1D[事务内有效]
        L1E[HashMap存储]
    end
    
    subgraph L2["二级缓存"]
        direction TB
        L2A[作用域: Mapper Namespace]
        L2B[默认关闭]
        L2C[需手动开启]
        L2D[跨Session有效]
        L2E[装饰器链存储]
    end
    
    L1 -.-> L2

8.5 关键要点
#

/**
 * MyBatis 核心要点总结
 */
public class MyBatisSummary {
    
    /*
     * ⭐ 初始化
     *    1. 解析 XML 配置文件 → Configuration
     *    2. 解析 Mapper.xml → MappedStatement
     *    3. 注册 Mapper 接口 → MapperRegistry
     *    4. 创建 SqlSessionFactory
     *
     * ⭐ Mapper 代理
     *    1. getMapper() → MapperProxyFactory.newInstance()
     *    2. JDK 动态代理创建代理对象
     *    3. 方法调用 → MapperProxy.invoke()
     *    4. 解析方法类型 → 调用 SqlSession 对应方法
     *
     * ⭐ SQL 执行
     *    1. Executor: 执行入口,管理缓存
     *    2. StatementHandler: 操作 JDBC Statement
     *    3. ParameterHandler: 设置 SQL 参数
     *    4. ResultSetHandler: 处理查询结果
     *    5. TypeHandler: Java ↔ JDBC 类型转换
     *
     * ⭐ 缓存机制
     *    1. 一级缓存: SqlSession 级别,默认开启
     *    2. 二级缓存: Mapper 级别,需要手动开启
     *    3. 装饰器模式: 灵活组合缓存功能
     *    4. 事务缓存: 保证数据一致性
     *
     * ⭐ 插件机制
     *    1. 基于 JDK 动态代理实现
     *    2. 可拦截: Executor, StatementHandler, 
     *              ParameterHandler, ResultSetHandler
     *    3. 责任链模式处理多个插件
     *    4. 使用 @Intercepts + @Signature 声明拦截点
     */
}