MyBatis架构原理解析:核心对象与执行流程深度剖析

一、开篇:理解MyBatis的核心价值

在当今Java持久层框架生态中,MyBatis凭借其灵活的SQL控制能力简洁的ORM实现成为企业级应用的首选。与JPA的全自动ORM不同,MyBatis采用半自动化映射理念,在保持SQL灵活性的同时,通过智能映射减少70%的JDBC样板代码。

开发者
直接编写SQL
MyBatis核心引擎
自动参数绑定
结果集映射
事务管理
JDBC

本文将深入剖析MyBatis的架构核心,通过源码解析揭示其内部工作机制。阅读本文后,您将掌握:

  1. MyBatis核心对象的职责与协作关系
  2. SQL从映射到执行的完整生命周期
  3. 配置文件加载的关键流程
  4. 执行器体系的运作原理

二、核心对象体系解析

1. 基础组件关系图

SqlSessionFactoryBuilder
+build(InputStream inputStream) : SqlSessionFactory
SqlSessionFactory
+openSession() : SqlSession
SqlSession
+selectOne(String statement)
+getMapper(Class type)
«interface»
Executor
+query(MappedStatement ms, Object parameter) : List
«interface»
StatementHandler
+prepare(Connection connection)
+parameterize(Statement statement)

2. 核心对象职责说明

(1) SqlSessionFactoryBuilder
  • 功能:根据配置信息构建SqlSessionFactory
  • 生命周期:方法局部(构建后即可销毁)
  • 源码关键路径
public class SqlSessionFactoryBuilder {public SqlSessionFactory build(Reader reader) {return build(reader, null, null);}public SqlSessionFactory build(InputStream inputStream) {return build(inputStream, null, null);}.....}
(2) SqlSessionFactory
  • 功能:创建SqlSession实例
  • 实现类DefaultSqlSessionFactory
  • 核心方法
public class DefaultSqlSessionFactory implements SqlSessionFactory {private final Configuration configuration;public DefaultSqlSessionFactory(Configuration configuration) {this.configuration = configuration;}@Overridepublic SqlSession openSession() {return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);}
......}
(3) SqlSession
  • 功能:执行CRUD操作、获取Mapper接口
  • 实现类DefaultSqlSession
  • 关键源码
public class DefaultSqlSession implements SqlSession {private final Configuration configuration;private final Executor executor;private final boolean autoCommit;private boolean dirty;private List<Cursor<?>> cursorList;public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {this.configuration = configuration;this.executor = executor;this.dirty = false;this.autoCommit = autoCommit;}public DefaultSqlSession(Configuration configuration, Executor executor) {this(configuration, executor, false);}@Overridepublic <T> T selectOne(String statement) {return this.selectOne(statement, null);}......}
(4) Executor执行器
类型特点适用场景
SimpleExecutor每次执行创建新Statement常规操作
ReuseExecutor复用预处理Statement高频相同SQL操作
BatchExecutor批量操作优化大批量数据插入/更新
(5) StatementHandler
  • 职责链
    1. 准备Statement对象
    2. 参数绑定
    3. 执行SQL
    4. 结果集映射
  • 核心实现PreparedStatementHandler

三、配置文件加载机制深度解析

1. 配置文件加载流程

App XMLConfigBuilder XMLMapperBuilder Configuration DefaultSqlSessionFactory parse() parse() addMappedStatement() 返回 完成 构建实例 返回 App XMLConfigBuilder XMLMapperBuilder Configuration DefaultSqlSessionFactory

2. 核心源码分析(MyBatis 3.5.10)

(1) XMLConfigBuilder 关键路径
public Configuration parse() {parseConfiguration(parser.evalNode("/configuration"));return configuration;
}private void parseConfiguration(XNode root) {propertiesElement(root.evalNode("properties"));typeAliasesElement(root.evalNode("typeAliases"));pluginsElement(root.evalNode("plugins"));objectFactoryElement(root.evalNode("objectFactory"));objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));settingsElement(root.evalNode("settings"));environmentsElement(root.evalNode("environments"));databaseIdProviderElement(root.evalNode("databaseIdProvider"));typeHandlerElement(root.evalNode("typeHandlers"));mapperElement(root.evalNode("mappers"));
}
(2) Mapper解析核心逻辑
// XMLMapperBuilder.java
private void configurationElement(XNode context) {String namespace = context.getStringAttribute("namespace");// 解析缓存配置cacheRefElement(context.evalNode("cache-ref"));cacheElement(context.evalNode("cache"));// 解析SQL片段sqlElement(context.evalNodes("/mapper/sql"));// 解析CRUD操作buildStatementFromContext(context.evalNodes("select|insert|update|delete"));
}

四、SQL执行全链路剖析

1. 执行流程时序图

App SqlSession Executor StatementHandler ParameterHandler ResultSetHandler Statement selectOne("com.example.UserMapper.findById", 101) query() prepare() setParameters() execute() handleResultSets() 返回结果对象 User实例 App SqlSession Executor StatementHandler ParameterHandler ResultSetHandler Statement

2. 核心阶段源码分析

(1) 执行器选择策略
// DefaultSqlSessionFactory.java
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {final Executor executor = configuration.newExecutor(tx, execType);return new DefaultSqlSession(configuration, executor, autoCommit);
}
(2) 参数绑定过程
// DefaultParameterHandler.java
public void setParameters(PreparedStatement ps) {for (int i = 0; i < parameterMappings.size(); i++) {ParameterMapping parameterMapping = parameterMappings.get(i);Object value;String property = parameterMapping.getProperty();// 获取参数值(支持复杂对象导航)value = parameterMapping.getTypeHandler().getParameter(parameterObject, property);// 设置到PreparedStatementtypeHandler.setParameter(ps, i + 1, value, jdbcType);}
}
(3) 结果集映射核心逻辑
// DefaultResultSetHandler.java
public List<Object> handleResultSets(Statement stmt) throws SQLException {final List<Object> multipleResults = new ArrayList<>();ResultSetWrapper rsw = getFirstResultSet(stmt);// 遍历结果集while (rsw != null) {// 处理单结果集Object resultObject = handleResultSet(rsw, resultMaps);multipleResults.add(resultObject);rsw = getNextResultSet(stmt);}return collapseSingleResultList(multipleResults);
}

五、生产级最佳实践

1. SqlSession使用规范

// 正确用法:确保资源释放
try (SqlSession session = sqlSessionFactory.openSession()) {UserMapper mapper = session.getMapper(UserMapper.class);User user = mapper.findById(101);// 业务处理...
} // 自动关闭session

2. 执行器选择策略

场景推荐执行器配置方式
常规单条操作SimpleExecutor默认配置
批量更新操作BatchExecutoropenSession(ExecutorType.BATCH)
高并发重复SQLReuseExecutoropenSession(ExecutorType.REUSE)

3. 二级缓存陷阱规避方案

问题场景

<!-- 错误配置:导致脏读 -->
<cache/>

解决方案

<!-- 正确配置:启用事务缓存 -->
<cache type="org.apache.ibatis.cache.TransactionalCache"/>

六、总结

本文深入剖析了MyBatis的核心架构运行机制,关键要点包括:

  1. 核心对象职责:SqlSessionFactoryExecutorStatementHandler的协作关系
  2. 配置文件加载:XML解析与Configuration对象构建过程
  3. SQL执行全链路:从映射到结果集转换的完整流程