# MyBatis(技术NeiMu):核心处理层(ResultSetHandler)

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

回顾

前面我们已经了解了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
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值