一、开篇:理解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;
}
@Override
public 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);
}
@Override
public <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);
// 设置到PreparedStatement
typeHandler.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执行全链路:从映射到结果集转换的完整流程