【源码解读之 Mybatis】【基础篇】-- 第篇:MyBatis 整体架构设计

发布时间:2026/7/27 19:02:32
【源码解读之 Mybatis】【基础篇】-- 第篇:MyBatis 整体架构设计 一、引言MyBatis 整体架构概览MyBatis 作为一款优秀的持久层框架其核心设计理念是SQL 与 Java 代码分离通过 XML 或注解配置将数据库操作映射为 Java 方法调用。理解 MyBatis 的整体架构是深入阅读源码、解决性能问题、进行二次开发的基础。从宏观角度看MyBatis 的架构可划分为三层1.接口层提供SqlSession等核心 API供开发人员直接使用。2.核心处理层负责 SQL 解析、参数映射、SQL 执行、结果映射等核心逻辑。3.基础支持层提供连接池管理、事务管理、配置加载、类型别名注册等基础能力。下面我们将通过代码实例逐层剖析其设计。—## 二、接口层SqlSession 的设计与实现SqlSession是 MyBatis 的门面接口它封装了所有数据库操作增删改查、提交、回滚。其实现类DefaultSqlSession是核心。### 2.1 源码片段SqlSession 接口定义java// 摘自 org.apache.ibatis.session.SqlSessionpublic interface SqlSession extends Closeable { // 查询单个对象 T T selectOne(String statement, Object parameter); // 查询列表 E ListE selectList(String statement, Object parameter); // 插入 int insert(String statement, Object parameter); // 更新 int update(String statement, Object parameter); // 删除 int delete(String statement, Object parameter); // 提交事务 void commit(); // 回滚事务 void rollback(); // 关闭会话释放连接 void close(); // 获取配置 Configuration getConfiguration();}### 2.2 实战示例通过 SqlSession 执行 SQL下面是一个完整的数据库查询示例展示SqlSession如何与底层交互。java// 1. 创建 SqlSessionFactory通常全局唯一String resource mybatis-config.xml;InputStream inputStream Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory new SqlSessionFactoryBuilder().build(inputStream);// 2. 获取 SqlSession自动管理事务try (SqlSession session sqlSessionFactory.openSession()) { // 3. 执行查询参数namespace sqlId User user session.selectOne(com.example.mapper.UserMapper.selectById, 1L); System.out.println(查询结果 user.getName()); // 4. 插入新用户 User newUser new User(); newUser.setName(张三); int rows session.insert(com.example.mapper.UserMapper.insertUser, newUser); System.out.println(影响行数 rows); // 5. 提交事务默认手动提交 session.commit();}关键点- 每个SqlSession对应一个数据库连接且非线程安全应每次请求创建新实例。- 所有的 SQL 操作最终都委托给Executor执行。—## 三、核心处理层Executor 与 MappedStatementExecutor是 MyBatis 执行 SQL 的核心调度器它负责缓存管理、数据库操作、事务控制。而MappedStatement封装了一条 SQL 的完整元数据ID、参数类型、结果映射、SQL 语句等。### 3.1 源码解读Executor 接口与实现链java// 摘自 org.apache.ibatis.executor.Executorpublic interface Executor { // 更新insert/update/delete int update(MappedStatement ms, Object parameter) throws SQLException; // 查询带缓存 E ListE query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql); // 提交事务 void commit(boolean required) throws SQLException; // 回滚事务 void rollback(boolean required) throws SQLException;}MyBatis 提供了三种Executor实现通过Configuration的defaultExecutorType配置| 实现类 | 特性 | 默认 ||-------------------|-------------------|--------||SimpleExecutor| 每次执行都创建新 Statement | 是 ||ReuseExecutor| 复用 PreparedStatement | 否 ||BatchExecutor| 批量执行 SQLJDBC Batch | 否 |### 3.2 实战示例自定义 Executor 拦截器通过 MyBatis 的插件机制我们可以拦截Executor的方法实现 SQL 审计或性能监控。下面是一个简单的耗时记录拦截器。java// 自定义拦截器记录所有查询耗时Intercepts({ Signature( type Executor.class, method query, args {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class} )})public class SqlTimeInterceptor implements Interceptor { Override public Object intercept(Invocation invocation) throws Throwable { long start System.currentTimeMillis(); // 执行目标方法真正的 SQL 查询 Object result invocation.proceed(); long end System.currentTimeMillis(); System.out.println(SQL 执行耗时 (end - start) ms); return result; } Override public Object plugin(Object target) { // 包装目标对象生成代理 return Plugin.wrap(target, this); }}运行效果当执行任何select操作时控制台都会打印 SQL 耗时。设计启示Executor的职责单一仅执行 SQL而插件机制通过代理模式实现了功能的横向扩展这正是架构中“开闭原则”的体现。—## 四、基础支持层Configuration 与 MapperRegistryConfiguration是 MyBatis 的全局配置中心存储了所有解析结果MappedStatement、类型别名、插件、环境配置等。MapperRegistry负责管理 Mapper 接口与代理对象的映射。### 4.1 源码片段Configuration 的核心字段java// 摘自 org.apache.ibatis.session.Configurationpublic class Configuration { // 所有 MappedStatementSQL 语句 protected final MapString, MappedStatement mappedStatements new StrictMap(Mapped Statements collection); // 所有 Mapper 接口的代理工厂 protected final MapperRegistry mapperRegistry new MapperRegistry(this); // 全局缓存 protected final MapString, Cache caches new HashMap(); // 类型别名如 int - Integer.class protected final TypeAliasRegistry typeAliasRegistry new TypeAliasRegistry(); // 插件列表 protected final InterceptorChain interceptorChain new InterceptorChain(); // 事务工厂 protected TransactionFactory transactionFactory; // 数据源 protected DataSource dataSource;}### 4.2 实战示例动态添加 MappedStatement在业务中有时需要动态生成 SQL如动态建表。我们可以直接操作Configuration手动注册一个MappedStatement。java// 动态注册一个查询语句public void registerDynamicSql(Configuration configuration) { // 1. 构建 MappedStatement.Builder String id com.example.mapper.DynamicMapper.selectDynamic; SqlSource sqlSource new RawSqlSource(configuration, SELECT * FROM dynamic_table WHERE id #{id}, Object.class); MappedStatement.Builder builder new MappedStatement.Builder( configuration, id, sqlSource, SqlCommandType.SELECT); // 2. 设置返回值类型 builder.resultMaps(Arrays.asList( new ResultMap.Builder(configuration, defaultResultMap, DynamicEntity.class, new ArrayList()).build() )); // 3. 注册到 Configuration MappedStatement ms builder.build(); configuration.addMappedStatement(ms);}// 使用动态注册的 SQLtry (SqlSession session sqlSessionFactory.openSession()) { // 动态注册需在初始化后调用 registerDynamicSql(session.getConfiguration()); // 执行动态 SQL DynamicEntity result session.selectOne( com.example.mapper.DynamicMapper.selectDynamic, 1L);}设计精髓Configuration就像 MyBatis 的“内核”所有配置、缓存、映射关系都集中管理而MappedStatement是 SQL 的“细胞单元”。通过直接操作这些底层对象我们可以实现高度定制化的功能。—## 五、整体架构设计图文字描述┌────────────────────────────────────────────────────────────┐│ 应用层API ││ SqlSession SqlSessionFactory MapperProxy │└──────────────────────────┬─────────────────────────────────┘ │ 委托┌──────────────────────────▼─────────────────────────────────┐│ 核心处理层 ││ ┌─────────┐ ┌─────────────┐ ┌─────────────────────┐ ││ │Executor │──│ParameterHandler│──│StatementHandler │ ││ └────┬────┘ └─────────────┘ └──────────┬──────────┘ ││ │ │ ││ ┌────▼────┐ ┌─────▼──────┐ ││ │Cache │ │ResultSetHandler│ ││ └─────────┘ └──────────────┘ │└──────────────────────────┬─────────────────────────────────┘ │ 依赖┌──────────────────────────▼─────────────────────────────────┐│ 基础支持层 ││ Configuration MapperRegistry TypeAliasRegistry ││ DataSource Transaction Logging Plugin │└────────────────────────────────────────────────────────────┘层次说明-应用层提供简洁的 API屏蔽内部复杂性。-核心处理层完成 SQL 解析、参数绑定、执行、结果映射的完整生命周期。-基础支持层提供配置管理、数据源、事务、日志等基础设施。—## 六、总结MyBatis 的整体架构设计遵循了分层抽象、职责单一的原则1.接口层SqlSession隔离了用户与底层复杂性体现了“门面模式”。2.核心处理层Executor、MappedStatement通过“策略模式”支持多种执行方式并通过“插件机制”实现可扩展。3.基础支持层Configuration作为全局配置中心通过“注册表模式”管理所有元数据。通过本文的源码片段和实战示例我们可以看到 MyBatis 并非黑盒而是一个高度模块化、可定制的框架。理解其架构设计不仅能帮助我们写出更高效的 SQL 映射代码还能在遇到性能瓶颈或需要定制功能时直接定位到关键类进行优化或扩展。后续文章我们将深入Executor的缓存机制和StatementHandler的 SQL 执行细节敬请期待。