回顾
前面我们已经了解了MyBatis的整个初始化过程,与SQL节点的解析与SQL节点的SQL是如何与实参进行绑定起来、如何根据实参进行动态拼接,下面来看一下MyBatis是如何处理结果集的
ResultSetHandler
MyBatis会根据SQL映射配置文件中定义的映射规则,比如resultMap标签、resultType属性来进行结果集映射,映射成相应的结果对象,而结果集映射机制是MyBatis的核心机制之一
当StatementHandler接口在执行完指定的select语句时候,就会调用ResultSetHandler来处理结果集,ResultSetHandler就是负责完成映射处理的,这里我们先不用知道StatementHandler如何执行SQL,我们只认识了DynamicSqlSource和RawSqlSource来存储SQL节点中完成解析的SQL而已

该接口提供三种方法,处理不同的结果集
- handlerResultSets:处理结果集,生成相应的结果对象集合
- handlerCursorResults:处理返回的游标对象
- handlerOutputParameters:处理存储过程的输出参数的
DefaultResultSetHandler
MyBatis仅仅只有一个DefaultResultSetHandler实现了ResultSetHandler接口

下面来介绍一下其比较重要的成员属性
- executor:处理器,用来执行SQL的
- configuration:MyBatis的上下文配置
- RawBounds:用于分页的
- mappedStatement:存储SQL节点的
- resultHandler:指定用于处理结果集的ResultHandler对象,ResultSetHandler其实是一个组合对象而已,真实处理是交由ResultHandler来进行
- TypeHandlerRegistry:类型转换注册中心
- ObjectFactory:用于实例对象工厂的
- ReflectorFactory:反射工厂,用于获取类的Reflector,根据Reflector可以创建对象出来
handlerResultSets方法
处理结果集映射的是handlerResultSets方法,该方法不仅可以处理普通的SQL语句(Statement)、也能处理预编译SQL(PrepareStatement),还有存储过程(CallableStatement)
源码如下
public List<Object> handleResultSets(Statement stmt) throws SQLException {
ErrorContext.instance().activity("handling results").object(mappedStatement.getId());
//使用List来存储所有的映射结果集得到的结果对象,因为支持存储过程,所以可能会存在多结果集!
//因此使用List来接收
final List<Object> multipleResults = new ArrayList<>();
int resultSetCount = 0;
//获取第一个ResultSet对象
ResultSetWrapper rsw = getFirstResultSet(stmt);
//通过MappedStatement获得ResultMaps对象,也就是对应的resultMap标签
//一个MappedStatement可能会拥有多个ResultMap对象
//但我们一般只会给SQL节点的resultMap属性设置一个id,其实可以使用逗号来分割使用多个ResultMap的
//当然这是要对应存在多结果集的时候才需要使用,也就是执行多条查询SQL,返回多个结果集
//每个结果集会有对应的ResultMap来进行映射
//前面在初始化MyBatis的时候就已经了解过了
List<ResultMap> resultMaps = mappedStatement.getResultMaps();
int resultMapCount = resultMaps.size();
//对resultMaps进行校验
validateResultMapsCount(rsw, resultMapCount);
//判空,如果结果集不为空,那么对应的ResultMap对象不能为空
while (rsw != null && resultMapCount > resultSetCount) {
//获取对应的ResultMap
ResultMap resultMap = resultMaps.get(resultSetCount);
//使用ResultMap去处理结果集
handleResultSet(rsw, resultMap, multipleResults, null);
//获取下一个结果集
rsw = getNextResultSet

本文深入探讨了MyBatis中的ResultSetHandler处理机制,特别是DefaultResultSetHandler如何根据ResultMap映射结果对象。内容包括handlerResultSets方法的执行流程,获取ResultSet的过程,以及ResultSetWrapper的角色和构造方法,展示了MyBatis对结果集的列映射和类型转换等关键步骤。
最低0.47元/天 解锁文章
6万+

被折叠的 条评论
为什么被折叠?



