MyBatis 核心類別架構
SqlSessionFactoryBuilder
↓ build()
SqlSessionFactory (介面)
↓ openSession()
DefaultSqlSessionFactory → DefaultSqlSession (核心實作)
↓ 內部持有
Configuration (全域配置)
↓ 包含
MapperRegistry → MapperProxyFactory → MapperProxy (動態代理)
↓
Executor (執行器介面)
↓ 三種實作
BaseExecutor (抽象基類)
├── SimpleExecutor (簡單執行)
├── ReuseExecutor (重用 PreparedStatement)
└── BatchExecutor (批次執行)
↓
StatementHandler (語句處理器)
├── SimpleStatementHandler
├── PreparedStatementHandler
└── CallableStatementHandler
↓
ParameterHandler / ResultSetHandler
核心流程:SqlSession 查詢執行
1. 入口:DefaultSqlSession.selectList()
public List selectList(String statement, Object parameter, RowBounds rowBounds) {
try {
MappedStatement ms = configuration.getMappedStatement(statement);
return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
2. 委派給 Executor
// BaseExecutor.query()
public List query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler handler) {
// 1. 建立緩存鍵
CacheKey key = createCacheKey(ms, parameter, rowBounds);
// 2. 緩存查詢 (CachingExecutor 會攔截)
List list = resultHandler == null ? (List) localCache.getObject(key) : null;
if (list != null) return list;
// 3. 實際查詢
list = queryFromDatabase(ms, parameter, rowBounds, handler, key, boundSql);
// 4. 存入本地緩存
localCache.putObject(key, list);
return list;
}
// 抽象方法留給子類實作
protected abstract List doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds,
ResultHandler handler, BoundSql boundSql);
3. SimpleExecutor 實作
public List doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds,
ResultHandler handler, BoundSql boundSql) {
Statement stmt = null;
try {
Configuration config = ms.getConfiguration();
// 1. 建立 StatementHandler
StatementHandler handler = config.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
// 2. 準備 Statement (預編譯、設定參數)
stmt = handler.prepare(connection, transaction.getTimeout());
// 3. 執行查詢並處理結果集
return handler.query(stmt, resultHandler);
} finally {
closeStatement(stmt);
}
}
4. StatementHandler 責任鏈
// PreparedStatementHandler.query()
public List query(Statement statement, ResultHandler resultHandler) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute(); // 執行 SQL
return resultSetHandler.handleResultSets(ps); // 委派結果集處理
}
// ResultSetHandler.handleResultSets()
public List
關鍵設計模式應用
| 模式 | 應用場景 | 核心類別 |
| 建造者模式 | SqlSessionFactory 建構 | SqlSessionFactoryBuilder, XMLConfigBuilder |
| 工廠模式 | StatementHandler/Executor 建立 | Configuration.newStatementHandler() |
| 模板方法 | BaseExecutor 定義查詢骨架 | query() → doQuery() |
| 策略模式 | Executor 三種實作切換 | Simple/Reuse/BatchExecutor |
| 代理模式 | Mapper 介面動態代理 | MapperProxy, MapperProxyFactory |
| 責任鏈 | 攔截器鏈 | InterceptorChain, Plugin |
| 裝飾模式 | CachingExecutor 包裝 BaseExecutor | CachingExecutor |
配置解析流程
XMLConfigBuilder 解析 mybatis-config.xml
public Configuration parse() {
// 1. 解析設定屬性
parseConfiguration(rootNode);
// 2. 解析類型別名
typeAliasesElement(rootNode);
// 3. 解析插件
pluginElement(rootNode);
// 4. 解析物件工廠/包裝工廠
objectFactoryElement(rootNode);
objectWrapperFactoryElement(rootNode);
// 5. 解析設定值 (settings)
settingsElement(rootNode);
// 6. 解析環境 (數據源、事務管理器)
environmentsElement(rootNode);
// 7. 解析映射器 (Mapper XML 掃描)
mapperElement(rootNode);
return configuration;
}
XMLMapperBuilder 解析 Mapper XML
// 解析
BoundSql 動態 SQL 產生
// DynamicSqlSource.getBoundSql()
public BoundSql getBoundSql(Object parameterObject) {
DynamicContext context = new DynamicContext(configuration, parameterObject);
rootSqlNode.apply(context); // OGNL 表達式評估、 等標籤處理
SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);
Class> parameterType = parameterObject == null ? Object.class : parameterObject.getClass();
SqlSource sqlSource = sqlSourceParser.parse(context.getSql(), parameterType, context.getBindings());
return sqlSource.getBoundSql(parameterObject);
}
下篇預告
- 攔截器機制與分頁插件實作原理
- 緩存架構:一級/二級緩存、CacheKey 設計
- 類型處理器 TypeHandler 體系
- 事務管理與 Spring 整合原理