
MyBatis首先需要加载配置文件构建SqlSessionFactory,其次获取会话SqlSession,通过会话获取数据库操作映射对象执行数据库操作,最后才是关闭会话。可以看到,核心在于获取会话工厂和创建会话。

java
public class MyBatisMain {
// MyBatis启动执行操作
// 1.加载全局配置文件
// 2.加载映射文件
// 3.配置内容存储Configuration
public static void main(String[] args) {
// 1. 获取配置文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
// 2. 加载解析配置文件通过Builder对象建造SqlSessionFactory对象
// 建造者模式: 构建复杂对象
// (1) 完成配置文件加载解析
// (2) 完成SqlSessionFactory创建
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
// 3. 根据SqlSessionFactory获取SqlSession对象
SqlSession sqlSession = factory.openSession();
// 4. 获取接口代码对象获得JDBC代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> list = mapper.selectUserList();
for (User user : list) {
System.out.println(user);
}
// 5. 关闭会话
sqlSession.close();
}
}
01 构建会话工厂
SqlSessionFactoryBuiler仅仅用来协助构建当前XML配置文件SqlSessionFactory对象,所以生命周期只存在于方法局部。
java
public class SqlSessionFactoryBuilder {
public SqlSessionFactory build(Reader reader) {
return build(reader, null, null);
}
public SqlSessionFactory build(Reader reader, String environment) {
return build(reader, environment, null);
}
public SqlSessionFactory build(Reader reader, Properties properties) {
return build(reader, null, properties);
}
public SqlSessionFactory build(Reader reader, String environment, Properties properties) {
try {
// XML配置文件构建者: 创建Configuration对象
// MyBatis配置文件: mybatis-config.xml
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
// 解析配置文件, 构建SqlSessionFactory
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
// 构建SqlSessionFactory
public SqlSessionFactory build(Configuration config) {
return new DefaultSqlSessionFactory(config);
}
}
02 构建会话
java
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);
}
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
Transaction tx = null;
try {
// 获取环境变量
final Environment environment = configuration.getEnvironment();
// 事务工厂
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
// 创建事务
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
// 根据事务工厂和执行器类型, 创建执行器
final Executor executor = configuration.newExecutor(tx, execType);
// 创建脚本会话
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
closeTransaction(tx);
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
private TransactionFactory getTransactionFactoryFromEnvironment(Environment environment) {
// 事务工厂: 默认ManagedTransactionFactory
if (environment == null || environment.getTransactionFactory() == null) {
return new ManagedTransactionFactory();
}
return environment.getTransactionFactory();
}
private void closeTransaction(Transaction tx) {
if (tx != null) {
try {
tx.close();
} catch (SQLException ignore) {
// Intentionally ignore. Prefer previous error.
}
}
}
}
2.1 创建事务
java
public class JdbcTransactionFactory implements TransactionFactory {
@Override
public Transaction newTransaction(Connection conn) {
return new JdbcTransaction(conn);
}
@Override
public Transaction newTransaction(DataSource ds, TransactionIsolationLevel level, boolean autoCommit) {
return new JdbcTransaction(ds, level, autoCommit);
}
}
2.2 创建执行器
java
public class Configuration {
// 默认执行器类型
protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
// 插件
protected final InterceptorChain interceptorChain = new InterceptorChain();
public Configuration() {
// 注册类型别名
typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);
}
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
executorType = executorType == null ? defaultExecutorType : executorType;
executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
Executor executor;
if (ExecutorType.BATCH == executorType) {
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
// 默认SimpleExecutor
executor = new SimpleExecutor(this, transaction);
}
// 二级缓存开关, 默认cacheEnabled=true
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
// 植入插件逻辑, 至此四大对象已经全部拦截完毕
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
}
03 获取映射对象
java
public class DefaultSqlSession implements SqlSession {
@Override
public <T> T getMapper(Class<T> type) {
return configuration.getMapper(type, this);
}
}
public class Configuration {
// 映射器注册中心
protected final MapperRegistry mapperRegistry = new MapperRegistry(this);
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
return mapperRegistry.getMapper(type, sqlSession);
}
}
3.1 创建映射对象
java
public class MapperRegistry {
private final Configuration config;
private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<>();
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
// 获取映射器代理工厂
final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
}
try {
// 创建映射器
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception e) {
throw new BindingException("Error getting mapper instance. Cause: " + e, e);
}
}
public <T> void addMapper(Class<T> type) {
// 必须接口
if (type.isInterface()) {
// 不能重复加载
if (hasMapper(type)) {
throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
}
boolean loadCompleted = false;
try {
// 缓存映射器代理工厂: XMLMapperBuilder#bindMapperForNamespace
knownMappers.put(type, new MapperProxyFactory<>(type));
// 解析映射器所有方法, 如@Select
MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
parser.parse();
loadCompleted = true;
} finally {
if (!loadCompleted) {
knownMappers.remove(type);
}
}
}
}
public <T> boolean hasMapper(Class<T> type) {
return knownMappers.containsKey(type);
}
}
3.2 映射代理工厂
java
public class MapperProxyFactory<T> {
// 映射器接口
private final Class<T> mapperInterface;
// 映射器方法调用者缓存
private final Map<Method, MapperMethodInvoker> methodCache = new ConcurrentHashMap<>();
public MapperProxyFactory(Class<T> mapperInterface) {
this.mapperInterface = mapperInterface;
}
@SuppressWarnings("unchecked")
// 创建映射器接口代理对象
protected T newInstance(MapperProxy<T> mapperProxy) {
// 1.类加载器
// 2.被代理类实现接口
// 3.实现InvocationHandler调用类
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[]{mapperInterface}, mapperProxy);
}
// 创建映射器接口代理对象
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
}
04 查询方法调用
java
public class MapperProxy<T> implements InvocationHandler, Serializable {
// 允许方法
private static final int ALLOWED_MODES = MethodHandles.Lookup.PRIVATE |
MethodHandles.Lookup.PROTECTED |
MethodHandles.Lookup.PACKAGE |
MethodHandles.Lookup.PUBLIC;
// 构造器
private static final Constructor<Lookup> lookupConstructor;
// 私有方法
private static final Method privateLookupInMethod;
// 会话
private final SqlSession sqlSession;
// 映射器类
private final Class<T> mapperInterface;
// 方法调用缓存
private final Map<Method, MapperMethodInvoker> methodCache;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
// 方法所在类为Object: 直接调用处理
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, args);
}
return cachedInvoker(method).invoke(proxy, method, args, sqlSession);
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
}
private MapperMethodInvoker cachedInvoker(Method method) throws Throwable {
try {
return methodCache.computeIfAbsent(method, m -> {
// 接口默认方法: default申明方法, 直接调用
if (m.isDefault()) {
try {
// java8
if (privateLookupInMethod == null) {
return new DefaultMethodInvoker(getMethodHandleJava8(method));
}
// java9
return new DefaultMethodInvoker(getMethodHandleJava9(method));
} catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e) {
throw new RuntimeException(e);
}
}
// 创建MapperMethod
return new PlainMethodInvoker(new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()));
});
} catch (RuntimeException re) {
Throwable cause = re.getCause();
throw cause == null ? re : cause;
}
}
private MethodHandle getMethodHandleJava8(Method method) throws IllegalAccessException, InstantiationException, InvocationTargetException {
final Class<?> declaringClass = method.getDeclaringClass();
return lookupConstructor.newInstance(declaringClass, ALLOWED_MODES).unreflectSpecial(method, declaringClass);
}
private MethodHandle getMethodHandleJava9(Method method) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
final Class<?> declaringClass = method.getDeclaringClass();
// 找到目标方法
return ((Lookup) privateLookupInMethod.invoke(null, declaringClass, MethodHandles.lookup()))
.findSpecial(declaringClass, method.getName(), MethodType.methodType(method.getReturnType(), method.getParameterTypes()), declaringClass);
}
}
java
public class MapperProxy<T> implements InvocationHandler, Serializable {
interface MapperMethodInvoker {
Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable;
}
private static class PlainMethodInvoker implements MapperMethodInvoker {
private final MapperMethod mapperMethod;
public PlainMethodInvoker(MapperMethod mapperMethod) {
super();
this.mapperMethod = mapperMethod;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable {
// SQL执行真正起点
return mapperMethod.execute(sqlSession, args);
}
}
private static class DefaultMethodInvoker implements MapperMethodInvoker {
private final MethodHandle methodHandle;
public DefaultMethodInvoker(MethodHandle methodHandle) {
super();
this.methodHandle = methodHandle;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable {
// 带参调用
return methodHandle.bindTo(proxy).invokeWithArguments(args);
}
}}
}
4.1 映射方法
java
public class MapperMethod {
// SQL命令, 如statementId=com.feiyu.mapper.BlogMapper.selectById
private final SqlCommand command;
// 方法签名, 主要读取返回值类型
private final MethodSignature method;
public MapperMethod(Class<?> mapperInterface, Method method, Configuration config) {
this.command = new SqlCommand(config, mapperInterface, method);
this.method = new MethodSignature(config, mapperInterface, method);
}
public Object execute(SqlSession sqlSession, Object[] args) {
Object result;
// SQL脚本类型
switch (command.getType()) {
case INSERT: {
// ParamNameResolver处理实参与指定参数名关联
Object param = method.convertArgsToSqlCommandParam(args);
// 结果处理
result = rowCountResult(sqlSession.insert(command.getName(), param));
break;
}
case UPDATE: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.update(command.getName(), param));
break;
}
case DELETE: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.delete(command.getName(), param));
break;
}
case SELECT:
// 方法返回值为空, 以及方法有结果处理器
if (method.returnsVoid() && method.hasResultHandler()) {
executeWithResultHandler(sqlSession, args);
result = null;
}
// 返回List类型数据
else if (method.returnsMany()) {
result = executeForMany(sqlSession, args);
}
// 返回Map数据类型
else if (method.returnsMap()) {
result = executeForMap(sqlSession, args);
}
// 返回游标
else if (method.returnsCursor()) {
result = executeForCursor(sqlSession, args);
} else {
// 返回单一对象方法
Object param = method.convertArgsToSqlCommandParam(args);
// 普通select语句执行入口
result = sqlSession.selectOne(command.getName(), param);
// 返回值类型为Optional
if (method.returnsOptional() &&
(result == null || !method.getReturnType().equals(result.getClass()))) {
result = Optional.ofNullable(result);
}
}
break;
case FLUSH:
// 刷新内存
result = sqlSession.flushStatements();
break;
default:
throw new BindingException("Unknown execution method for: " + command.getName());
}
// 基础类型必须有返回值
if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
throw new BindingException("Mapper method '" + command.getName() + " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");
}
return result;
}
}
4.2 查询列表
java
public class MapperMethod {
// SQL命令, 如statementId=com.feiyu.mapper.BlogMapper.selectById
private final SqlCommand command;
// 方法签名, 主要读取返回值类型
private final MethodSignature method;
private <E> Object executeForMany(SqlSession sqlSession, Object[] args) {
List<E> result;
// 参数转化
Object param = method.convertArgsToSqlCommandParam(args);
if (method.hasRowBounds()) {
RowBounds rowBounds = method.extractRowBounds(args);
// 再次调用会话拆线呢
result = sqlSession.selectList(command.getName(), param, rowBounds);
} else {
result = sqlSession.selectList(command.getName(), param);
}
// issue #510 Collections & arrays support
if (!method.getReturnType().isAssignableFrom(result.getClass())) {
// 数组
if (method.getReturnType().isArray()) {
return convertToArray(result);
}
// 集合类
return convertToDeclaredCollection(sqlSession.getConfiguration(), result);
}
return result;
}
private <E> Object convertToArray(List<E> list) {
Class<?> arrayComponentType = method.getReturnType().getComponentType();
Object array = Array.newInstance(arrayComponentType, list.size());
// 基础类型
if (arrayComponentType.isPrimitive()) {
// 基本类型包装类型
for (int i = 0; i < list.size(); i++) {
Array.set(array, i, list.get(i));
}
return array;
} else {
return list.toArray((E[]) array);
}
}
private <E> Object convertToDeclaredCollection(Configuration config, List<E> list) {
// 通过ObjectFactory创建对象反射方式
Object collection = config.getObjectFactory().create(method.getReturnType());
// 创建MetaObject对象
MetaObject metaObject = config.newMetaObject(collection);
metaObject.addAll(list);
return collection;
}
}
05 会话执行查询
java
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 {
// 获取映射语句
MappedStatement ms = configuration.getMappedStatement(statement);
// 如果开启二级缓存, Executor会被CachingExecutor装饰
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();
}
}
private Object wrapCollection(final Object object) {
// 集合类型
if (object instanceof Collection) {
StrictMap<Object> map = new StrictMap<>();
map.put("collection", object);
if (object instanceof List) {
map.put("list", object);
}
return map;
}
// 数组类型
if (object != null && object.getClass().isArray()) {
StrictMap<Object> map = new StrictMap<>();
map.put("array", object);
return map;
}
return object;
}
}
5.1 基础执行器
java
public abstract class BaseExecutor implements Executor {
// 事务
protected Transaction transaction;
// 执行器
protected Executor wrapper;
protected ConcurrentLinkedQueue<DeferredLoad> deferredLoads;
// 结果处理器缓存
protected PerpetualCache localCache;
// 输入参数缓存
protected PerpetualCache localOutputParameterCache;
// 全局配置
protected Configuration configuration;
// 查询栈深度
protected int queryStack;
// 是否已关闭
private boolean closed;
@Override
public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
BoundSql boundSql = ms.getBoundSql(parameter);
// 创建缓存键: 一级缓存和二级缓存是同一个
CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql);
return query(ms, parameter, rowBounds, resultHandler, key, boundSql);
}
@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.");
}
// flushCache=true: 强制清空缓存
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();
// 缓存级别: Statement
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;
}
5.2 简单执行器
java
public class SimpleExecutor extends BaseExecutor {
public SimpleExecutor(Configuration configuration, Transaction transaction) {
super(configuration, transaction);
}
@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();
// SQL处理关键对象StatementHandler
StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
// 获取Statement对象
stmt = prepareStatement(handler, ms.getStatementLog());
// 执行查询
return handler.query(stmt, resultHandler);
} finally {
// 用完就关闭
closeStatement(stmt);
}
}
private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
Statement stmt;
// 获取数据库链接
Connection connection = getConnection(statementLog);
// 获取Statement对象
stmt = handler.prepare(connection, transaction.getTimeout());
// 处理动态参数
handler.parameterize(stmt);
return stmt;
}
}
05 语句处理
java
public class RoutingStatementHandler implements StatementHandler {
// 封装真正StatementHandler对象
private final StatementHandler delegate;
public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
// StatementType根据增删改查标签statementType="PREPARED"配置, 默认值PREPARED
switch (ms.getStatementType()) {
case STATEMENT:
delegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
case PREPARED:
delegate = new PreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
case CALLABLE:
delegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
default:
throw new ExecutorException("Unknown statement type: " + ms.getStatementType());
}
}
@Override
public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
return delegate.prepare(connection, transactionTimeout);
}
@Override
public void parameterize(Statement statement) throws SQLException {
delegate.parameterize(statement);
}
@Override
public void batch(Statement statement) throws SQLException {
delegate.batch(statement);
}
@Override
public int update(Statement statement) throws SQLException {
return delegate.update(statement);
}
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
return delegate.query(statement, resultHandler);
}
@Override
public <E> Cursor<E> queryCursor(Statement statement) throws SQLException {
return delegate.queryCursor(statement);
}
@Override
public BoundSql getBoundSql() {
return delegate.getBoundSql();
}
@Override
public ParameterHandler getParameterHandler() {
return delegate.getParameterHandler();
}
}
5.1 PreparedStatementHandler
java
public class PreparedStatementHandler extends BaseStatementHandler {
public PreparedStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
super(executor, mappedStatement, parameter, rowBounds, resultHandler, boundSql);
}
@Override
public void batch(Statement statement) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
// 添加到批处理
ps.addBatch();
}
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
// 执行
ps.execute();
// 结果处理器, 返回结果
return resultSetHandler.handleResultSets(ps);
}
// 处理参数
@Override
public void parameterize(Statement statement) throws SQLException {
parameterHandler.setParameters((PreparedStatement) statement);
}
}
5.2 结果处理
java
public class DefaultResultSetHandler implements ResultSetHandler {
// 支持结果集类型: Statement、PreparedStatement和CallableStatement,
// 其中CallableStatement存储过程可能返回多个ResultSet对象
@Override
public List<Object> handleResultSets(Statement stmt) throws SQLException {
ErrorContext.instance().activity("handling results").object(mappedStatement.getId());
// 保存映射结果集对象
final List<Object> multipleResults = new ArrayList<>();
// 结果集数量
int resultSetCount = 0;
// 获取第一个ResultSet对象
ResultSetWrapper rsw = getFirstResultSet(stmt);
// 如果SQL能够产生多个ResultSet, 那么resultMap可以配置多个<resultMap>, 实现对多个结果集映射
List<ResultMap> resultMaps = mappedStatement.getResultMaps();
// 获取resultMap个数
int resultMapCount = resultMaps.size();
// 如果结果集不为空, 那么resultMaps不能为空, 否则抛异常
validateResultMapsCount(rsw, resultMapCount);
// 遍历resultMaps集合
while (rsw != null && resultMapCount > resultSetCount) {
// 获取循环ResultMap对象
ResultMap resultMap = resultMaps.get(resultSetCount);
// 处理单个ResultSet对象, 也就是根据resultMap定义规则映射ResultSet
// 并将单个结果映射添加到multipleResults
handleResultSet(rsw, resultMap, multipleResults, null);
rsw = getNextResultSet(stmt);// 获取下一个结果集
cleanUpAfterHandlingResultSet(); // 清空nestedResultObjects
resultSetCount++;
}
// resultSets仅对多结果集情况适用, 语句执行后返回结果集逗号分隔名称
String[] resultSets = mappedStatement.getResultSets();
if (resultSets != null) {
while (rsw != null && resultSetCount < resultSets.length) {
ResultMapping parentMapping = nextResultMaps.get(resultSets[resultSetCount]);
if (parentMapping != null) {
String nestedResultMapId = parentMapping.getNestedResultMapId();
ResultMap resultMap = configuration.getResultMap(nestedResultMapId);
handleResultSet(rsw, resultMap, null, parentMapping);
}
rsw = getNextResultSet(stmt);
cleanUpAfterHandlingResultSet();
resultSetCount++;
}
}
return collapseSingleResultList(multipleResults);
}
// 获取第一个ResultSet对象
private ResultSetWrapper getFirstResultSet(Statement stmt) throws SQLException {
ResultSet rs = stmt.getResultSet(); // 获取ResultSet对象
while (rs == null) {
if (stmt.getMoreResults()) { // 检测是否有待处理ResultSet
rs = stmt.getResultSet();
} else {
if (stmt.getUpdateCount() == -1) { // 没有待处理ResultSet对象
break;
}
}
}
// 结果集封装为ResultSetWrapper对象
return rs != null ? new ResultSetWrapper(rs, configuration) : null;
}
// 如果结果集不为空, 那么resultMaps不能为空, 否则抛异常
private void validateResultMapsCount(ResultSetWrapper rsw, int resultMapCount) {
if (rsw != null && resultMapCount < 1) {
throw new ExecutorException("A query was run and no Result Maps were found for the Mapped Statement '" + mappedStatement.getId() + "'. It's likely that neither a Result Type nor a Result Map was specified.");
}
}
// 映射单个结果集
private void handleResultSet(ResultSetWrapper rsw, ResultMap resultMap, List<Object> multipleResults, ResultMapping parentMapping) throws SQLException {
try {
if (parentMapping != null) {
// 处理多结果集嵌套映射
handleRowValues(rsw, resultMap, null, RowBounds.DEFAULT, parentMapping);
} else {
// 单结果集处理
if (resultHandler == null) {
// 如果用户没有指定处理映射结果ResultHandler对象, 则使用默认的
DefaultResultHandler defaultResultHandler = new DefaultResultHandler(objectFactory);
// 映射ResultSet结果添加到DefaultResultHandler暂存
handleRowValues(rsw, resultMap, defaultResultHandler, rowBounds, null);
// DefaultResultHandler保存结果添加到multipleResults对象
multipleResults.add(defaultResultHandler.getResultList());
} else {
handleRowValues(rsw, resultMap, resultHandler, rowBounds, null);
}
}
} finally {
// issue #228 (close resultsets) resultSet.close()
closeResultSet(rsw.getResultSet());
}
}
public void handleRowValues(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
if (resultMap.hasNestedResultMaps()) { // 处理嵌套映射
ensureNoRowBounds();
checkResultHandler();
handleRowValuesForNestedResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);
} else {// 处理简单映射
handleRowValuesForSimpleResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);
}
}
private void handleRowValuesForSimpleResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
DefaultResultContext<Object> resultContext = new DefaultResultContext<>();
ResultSet resultSet = rsw.getResultSet();
skipRows(resultSet, rowBounds); // 根据offset定位到指定位置
// 检测引进处理行数是否已经达到了上限(RowBounds.limit), 以及是否还有待处理记录
while (shouldProcessMoreRows(resultContext, rowBounds) && !resultSet.isClosed() && resultSet.next()) {
// 获取映射对象ResultMap
ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(resultSet, resultMap, null);
// 根据ResultMap处理ResultSet结果集
Object rowValue = getRowValue(rsw, discriminatedResultMap, null);
// 保存映射得到结果对象
storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
}
}
}