MyBatis 工作流程

121 阅读3分钟

MyBatis 工作流程详解

MyBatis 的工作流程分为 初始化阶段运行时阶段(读/写操作),以下是详细步骤解析:

一、初始化阶段

目标:加载配置并构建 SqlSessionFactory流程

  1. 解析全局配置mybatis-config.xml):

    • 加载数据源、事务管理器、插件、类型处理器等配置。
    • 解析 <environments> 确定数据库连接信息。
    <!-- mybatis-config.xml -->
    <environments default="dev">
        <environment id="dev">
            <dataSource type="POOLED">...</dataSource>
            <transactionManager type="JDBC"/>
        </environment>
    </environments>
    
  2. 解析 Mapper 文件

    • 扫描 XML 或注解定义的 SQL 语句,构建 MappedStatement 对象(包含 SQL ID、参数映射、结果映射等)。
    <!-- UserMapper.xml -->
    <mapper namespace="com.example.UserMapper">
        <select id="selectUser" resultType="User">
            SELECT * FROM user WHERE id = #{id}
        </select>
    </mapper>
    
  3. 构建 SqlSessionFactory

    • 将解析后的配置信息存入 Configuration 对象,最终生成全局唯一的 SqlSessionFactory

二、运行时阶段(读操作)

目标:执行查询并返回结果。 流程

  1. 创建 SqlSession

    • 通过 SqlSessionFactory.openSession() 创建会话(默认开启一级缓存)。
    SqlSession session = sqlSessionFactory.openSession();
    
  2. 获取 Mapper 代理对象

    • 通过动态代理生成 UserMapper 接口的实现类。
    UserMapper mapper = session.getMapper(UserMapper.class);
    
  3. SQL 解析与参数绑定

    • 根据方法名 selectUser 找到对应的 MappedStatement
    • 解析动态 SQL(如 <if> 标签),生成静态 SQL 并绑定参数。
  4. 执行 SQL

    • 执行器(Executor) 调用 StatementHandler 创建 PreparedStatement
    • 参数处理器(ParameterHandler) 将 Java 对象转换为 JDBC 参数。
    // 伪代码:参数映射示例
    pstmt.setInt(1, id); // 将 #{id} 替换为实际值
    
  5. 结果集映射

    • 结果集处理器(ResultSetHandler)ResultSet 转换为 User 对象(自动或通过 ResultMap)。
    • 若开启二级缓存,缓存结果。
  6. 返回结果

    User user = mapper.selectUser(1);
    

三、运行时阶段(写操作)

目标:执行插入/更新/删除操作,管理事务。 流程

  1. 开启事务

    • 默认情况下,SqlSession 不会自动提交事务(需手动调用 commit())。
    SqlSession session = sqlSessionFactory.openSession(); // 自动提交设为 false
    
  2. 执行写操作

    • 与读操作类似,通过执行器调用 update() 方法。
    int rows = mapper.updateUser(user);
    
  3. 事务提交/回滚

    • 成功时提交:session.commit();
    • 异常时回滚:session.rollback();
  4. 关闭会话

    session.close(); // 释放连接,清空一级缓存
    

四、核心流程图示

初始化阶段
解析mybatis-config.xml
解析Mapper XML/注解
构建SqlSessionFactory
运行时读操作
创建SqlSession
获取Mapper代理
解析SQL与参数
Executor执行SQL
ResultSet映射结果
运行时写操作
开启事务
执行更新操作
提交/回滚事务

五、关键机制

  1. 一级缓存

    • 作用范围:SqlSession 级别,相同查询直接返回缓存对象。
    • 失效场景:执行更新操作或调用 clearCache()
  2. 二级缓存

    • 作用范围:跨 SqlSession,需在 Mapper XML 中配置 <cache/>
    • 序列化要求:实体类需实现 Serializable
  3. 动态 SQL

    • 使用 <if>, <foreach> 等标签生成动态条件,避免 SQL 注入。

六、示例场景

批量插入优化

try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
    UserMapper mapper = session.getMapper(UserMapper.class);
    for (User user : userList) {
        mapper.insertUser(user); // 批量模式缓存 SQL,最后一次性提交
    }
    session.commit(); // 统一提交,减少数据库交互
}

总结

MyBatis 工作流程分为初始化(加载配置)和运行时(SQL 解析、执行、结果映射),通过 SqlSession 管理会话,Executor 控制执行策略,支持动态 SQL 和缓存机制,兼顾灵活性与性能,适合需精细控制 SQL 的场景。