详细步骤
PreparedStatementHandler#query
@Override public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException { PreparedStatement ps = (PreparedStatement) statement; // 执行SQL ps.execute(); // 结果集处理 return resultSetHandler.handleResultSets(ps); }
DefaultResultSetHandler#handleResultSets
/** * 处理statement得到的多结果集(也可能是单结果集,这是多结果集的一种简化形式),最终得到结果列表 * * handleResultSets 方法完成了对多结果集的处理。但是对于每一个结果集的处理是由handleResultSet子方法实现的 * @param stmt Statement语句 * @return 结果列表 * @throws SQLException */ @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; // 可能会有多个结果集,先取出第一个结果集 ResultSetWrapper rsw = getFirstResultSet(stmt); // 查询语句对应的resultMap节点,可能含有多个 List<ResultMap> resultMaps = mappedStatement.getResultMaps(); int resultMapCount = resultMaps.size(); // 合法性校验(存在输出结果集的情况下,resultMapCount不能为0) validateResultMapsCount(rsw, resultMapCount); // 循环遍历每一个设置了resultMap的结果集 while (rsw != null && resultMapCount > resultSetCount) { // 获得当前结果集对应的ResultMap ResultMap resultMap = resultMaps.get(resultSetCount); // 进行结果集的处理 handleResultSet(rsw, resultMap, multipleResults, null); // 获取下一结果集 rsw = getNextResultSet(stmt); // 清理上一条结果集的环境 cleanUpAfterHandlingResultSet(); resultSetCount++; } // 获取多结果集中所有结果集的名称 String[] resultSets = mappedStatement.getResultSets(); if (resultSets != null) { // 循环遍历每一个设置resultMap的结果集 while (rsw != null && resultSetCount < resultSets.length) { // 获取该结果集对应的父级resultMap中的resultMapping(注:resultMapping用来描述对象属性的映射关系) ResultMapping parentMapping = nextResultMaps.get(resultSets[resultSetCount]); if (parentMapping != null) { // 获取被嵌套的resultMap编号 String nestedResultMapId = parentMapping.getNestedResultMapId(); ResultMap resultMap = configuration.getResultMap(nestedResultMapId); // 处理嵌套映射 handleResultSet(rsw, resultMap, null, parentMapping); } rsw = getNextResultSet(stmt); cleanUpAfterHandlingResultSet(); resultSetCount++; } } // 判断是否为单结果集:如果是,则返回结果列表;如果不是则返回结果集列表 return collapseSingleResultList(multipleResults); }
DefaultResultSetHandler#handleResultSet
/** * 处理单一的结果集 * @param rsw ResultSet 的包装 * @param resultMap resultMap节点信息 * @param multipleResults 用来存储处理结果的列表 * @param parentMapping * @throws SQLException */ private void handleResultSet(ResultSetWrapper rsw, ResultMap resultMap, List<Object> multipleResults, ResultMapping parentMapping) throws SQLException { try { if (parentMapping != null) { // 嵌套的结果 // 向子方法闯入parentMapping。处理结果中的记录 handleRowValues(rsw, resultMap, null, RowBounds.DEFAULT, parentMapping); } else { // 非嵌套的结果 if (resultHandler == null) { // defaultResultHandler 能够将结果对象聚合成一个列表返回 DefaultResultHandler defaultResultHandler = new DefaultResultHandler(objectFactory); // 处理结果中的记录 handleRowValues(rsw, resultMap, defaultResultHandler, rowBounds, null); // 添加处理后的结果 multipleResults.add(defaultResultHandler.getResultList()); } else { handleRowValues(rsw, resultMap, resultHandler, rowBounds, null); } } } finally { // issue #228 (close resultsets) closeResultSet(rsw.getResultSet()); } }
DefaultResultSetHandler#handleRowValuesForSimpleResultMap
/** * 处理非嵌套映射的结果 * @param rsw 结果集包装 * @param resultMap 结果映射 * @param resultHandler 结果处理器 * @param rowBounds 翻页限制条件 * @param parentMapping 父级结果映射 * @throws SQLException */ 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); // 持续处理下一条结果,判断条件为;还有结果需要处理 && 结果集没有关闭 && 还有下一条结果 while (shouldProcessMoreRows(resultContext, rowBounds) && !resultSet.isClosed() && resultSet.next()) { // 经过鉴别器鉴别,确定经过鉴别器分析的最终要使用resultMap ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(resultSet, resultMap, null); // 拿到一行记录,并且将其转化为一个对象 Object rowValue = getRowValue(rsw, discriminatedResultMap, null); // 把这一行记录转化出的对象存起来 storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet); } }
DefaultResultSetHandler#getRowValue
- 解析ResultMap标签时,会将属性的TypeHandler确定下来
/** * 将一条记录转化为一个对象 * @param rsw 结果集包装 * @param resultMap 结果映射 * @param columnPrefix 列前缀 * @return 转化得到的对象 * @throws SQLException */ private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap, String columnPrefix) throws SQLException { final ResultLoaderMap lazyLoader = new ResultLoaderMap(); // 创建这一行记录对应的空对象 Object rowValue = createResultObject(rsw, resultMap, lazyLoader, columnPrefix); if (rowValue != null && !hasTypeHandlerForResultObject(rsw, resultMap.getType())) { // 根据对象得到其MetaObject final MetaObject metaObject = configuration.newMetaObject(rowValue); boolean foundValues = this.useConstructorMappings; // 是否允许自动映射未明示的字段 if (shouldApplyAutomaticMappings(resultMap, false)) { // 自动映射未明示的字段(resultType),映射时的TypeHandler通过属性名与set方法参数类型的映射来获取属性的类型,并据此获取对应的TypeHandler foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, columnPrefix) || foundValues; } // 按照明示的字段进行重新映射(resultMap),解析XML时获取TypeHandler foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, columnPrefix) || foundValues; foundValues = lazyLoader.size() > 0 || foundValues; rowValue = foundValues || configuration.isReturnInstanceForEmptyRow() ? rowValue : null; } return rowValue; }
以上便是Mybatis中ResultSet结果集处理流程。