01|核心类
- SqlSessionFactoryBuilder:负责构建SqlSessionFactory
- SqlSessionFactory:负责构建SqlSession
- SqlSession:mybatis操作数据库的顶层接口
- Executor:执行增删改查的具体执行器
- ParameterHandler:参数解析器
- StatementHandler:Statement的处理器
- ResultSetHandler:结果集处理器
- Configuration:全局配置类
- MappedStatement:映射信息描述类
02|配置解析
```java public class SqlSessionFactoryBuilder{ public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
} }XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
return build(parser.parse());
public class XMLConfigBuilder{ public Configuration parse() { if (parsed) { throw new BuilderException(“Each XMLConfigBuilder can only be used once.”); } parsed = true; // 解析XML配置文件中的所有配置属性并存入Configuration对象中 parseConfiguration(parser.evalNode(“/configuration”)); return configuration; }
private void parseConfiguration(XNode root) { try { //依次解析所有配置项信息 propertiesElement(root.evalNode(“properties”)); Properties settings = settingsAsProperties(root.evalNode(“settings”)); loadCustomVfs(settings); loadCustomLogImpl(settings); typeAliasesElement(root.evalNode(“typeAliases”)); pluginElement(root.evalNode(“plugins”)); objectFactoryElement(root.evalNode(“objectFactory”)); objectWrapperFactoryElement(root.evalNode(“objectWrapperFactory”)); reflectorFactoryElement(root.evalNode(“reflectorFactory”)); settingsElement(settings); environmentsElement(root.evalNode(“environments”)); databaseIdProviderElement(root.evalNode(“databaseIdProvider”)); typeHandlerElement(root.evalNode(“typeHandlers”)); // 解析mapper配置信息,并封装为MappedStatement放入Configuration对象中 // MapperdStatement对象中包含的sql语句执行的所有细节信息 mapperElement(root.evalNode(“mappers”)); } catch (Exception e) { throw new BuilderException(“Error parsing SQL Mapper Configuration. Cause: “ + e, e); } } }
当配置解析完毕,有关mybatis所需的所有配置项项目全部存入到了Configuration对象当中。
<a name="Mshpl"></a>
## 03|SQL执行流程
以SqlSession.selectList()为例进行源码分析
```java
@Test
public void query() throws IOException {
final SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
final SqlSession sqlSession = factory.openSession();
final List<Object> results = sqlSession.selectList("statement id");
}
SqlSession默认实现类为DefaultSqlSession
public class DefaultSqlSession implements SqlSession {
@Override
public <E> List<E> selectList(String statement) {
return this.selectList(statement, null);
}
@Override
public <E> List<E> selectList(String statement, Object parameter) {
return this.selectList(statement, parameter, RowBounds.DEFAULT);
}
@Override
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
try {
// 根据statementid从configuration配置中获取对应的MapperdStatement对象
MappedStatement ms = configuration.getMappedStatement(statement);
// 调用Executor执行具体的查询逻辑
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();
}
}
}
Executor拥有一个抽象子类BaseExecutor,Mybatis此处使用模版设计模式在BaseExecutor中封装一些列模版方法
public abstract class BaseExecutor implements Executor {
@Override
public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());
if (closed) {
throw new ExecutorException("Executor was closed.");
}
if (queryStack == 0 && ms.isFlushCacheRequired()) {
clearLocalCache();
}
List<E> list;
try {
queryStack++;
// 尝试从缓存中查找数据,如存在则不再从数据库查询
list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;
if (list != null) {
handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
} else {
// 从数据库获取数据,调用模版方法,由子类去实现
list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
}
} finally {
queryStack--;
}
if (queryStack == 0) {
for (DeferredLoad deferredLoad : deferredLoads) {
deferredLoad.load();
}
// issue #601
deferredLoads.clear();
if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
// issue #482
clearLocalCache();
}
}
return list;
}
private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
List<E> list;
localCache.putObject(key, EXECUTION_PLACEHOLDER);
try {
list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
} finally {
localCache.removeObject(key);
}
localCache.putObject(key, list);
if (ms.getStatementType() == StatementType.CALLABLE) {
localOutputParameterCache.putObject(key, parameter);
}
return list;
}
protected abstract <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)
throws SQLException;
}
BaseExecutor的默认实现类为SimpleExecutor
public class SimpleExecutor extends BaseExecutor {
@Override
public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
Statement stmt = null;
try {
Configuration configuration = ms.getConfiguration();
// 创建StatementHandler,此处创建的是RoutingStatementHadnler,会依据StatementType创建对应的StatementHandler
StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
stmt = prepareStatement(handler, ms.getStatementLog());
// 真正执行查询操作
return handler.query(stmt, resultHandler);
} finally {
closeStatement(stmt);
}
}
}
public class SimpleStatementHandler extends BaseStatementHandler {
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
String sql = boundSql.getSql();
statement.execute(sql);
// 返回由ResultSetHandler处理之后的查询结果
return resultSetHandler.handleResultSets(statement);
}
}