一、开篇:理解MyBatis的核心价值
在当今Java持久层框架生态中,MyBatis凭借其灵活的SQL控制能力和简洁的ORM实现成为企业级应用的首选。与JPA的全自动ORM不同,MyBatis采用半自动化映射理念,在保持SQL灵活性的同时,通过智能映射减少70%的JDBC样板代码。
本文将深入剖析MyBatis的架构核心,通过源码解析揭示其内部工作机制。阅读本文后,您将掌握:
- MyBatis核心对象的职责与协作关系
- SQL从映射到执行的完整生命周期
- 配置文件加载的关键流程
- 执行器体系的运作原理
二、核心对象体系解析
1. 基础组件关系图
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
- 职责链:
- 准备Statement对象
- 参数绑定
- 执行SQL
- 结果集映射
- 核心实现:
PreparedStatementHandler
三、配置文件加载机制深度解析
1. 配置文件加载流程
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. 执行流程时序图
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 | 默认配置 |
批量更新操作 | BatchExecutor | openSession(ExecutorType.BATCH) |
高并发重复SQL | ReuseExecutor | openSession(ExecutorType.REUSE) |
3. 二级缓存陷阱规避方案
问题场景:
<!-- 错误配置:导致脏读 -->
<cache/>
解决方案:
<!-- 正确配置:启用事务缓存 -->
<cache type="org.apache.ibatis.cache.TransactionalCache"/>
六、总结
本文深入剖析了MyBatis的核心架构与运行机制,关键要点包括:
- 核心对象职责:
SqlSessionFactory
、Executor
、StatementHandler
的协作关系 - 配置文件加载:XML解析与
Configuration
对象构建过程 - SQL执行全链路:从映射到结果集转换的完整流程