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@Testpublic 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 {@Overridepublic <E> List<E> selectList(String statement) {return this.selectList(statement, null);}@Overridepublic <E> List<E> selectList(String statement, Object parameter) {return this.selectList(statement, parameter, RowBounds.DEFAULT);}@Overridepublic <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 {@Overridepublic <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 #601deferredLoads.clear();if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {// issue #482clearLocalCache();}}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 {@Overridepublic <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创建对应的StatementHandlerStatementHandler 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 {@Overridepublic <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {String sql = boundSql.getSql();statement.execute(sql);// 返回由ResultSetHandler处理之后的查询结果return resultSetHandler.handleResultSets(statement);}}
