MyBatis源码解析之ResultSetHandler接口
2019-10-06 10:23
183 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_45492007/article/details/102214213
1.查看ResultSetHandler接口的结构
2.查看ResultSetHandler的源码
public interface ResultSetHandler { //处理结果集为List集合,当前的statement具有ResultSet <E> List<E> handleResultSets(Statement stmt) throws SQLException; //处理结果集为Cursor,当前的statement具有ResultSet <E> Cursor<E> handleCursorResultSets(Statement stmt) throws SQLException; void handleOutputParameters(CallableStatement cs) throws SQLException; }
发现当前这个接口就是专门用来处理ResultSet,将其变为List集合或者Cursor
3.查看DefaultResultSetHandler的源码
3.1 查看DefaultResultSetHandler类中的handleResultSets方法
@Override public List<Object> handleResultSets(Statement stmt) throws SQLException { ErrorContext.instance().activity("handling results").object(mappedStatement.getId()); //创建一个结果集使用Object的List集合接收 final List<Object> multipleResults = new ArrayList<Object>(); //定义结果集的数量 int resultSetCount = 0; //获取第一条结果集,并得到结果集包装类对象 ResultSetWrapper rsw = getFirstResultSet(stmt); //获取结果集对应的ResultMap,就是再UsersMapper.xml中定义的ResultMap List<ResultMap> resultMaps = mappedStatement.getResultMaps(); //获取ResultMap的数量 int resultMapCount = resultMaps.size(); //校验ResultMap的数量 validateResultMapsCount(rsw, resultMapCount); //通过循环的方式获取结果的Map while (rsw != null && resultMapCount > resultSetCount) { ResultMap resultMap = resultMaps.get(resultSetCount);//获取结果Map //然后开始处获取的数据,将获取的Map数据转换为包装数据放入集合中 handleResultSet(rsw, resultMap, multipleResults, null); rsw = getNextResultSet(stmt);//然后获取下一个包装(就是需要转换的类型) cleanUpAfterHandlingResultSet();//然后清理映射结果集 resultSetCount++;//游标往下走 } //再次获取结果集, 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); }
发现当前的handleResultSets方法中就是通过循环的方式获取,当前需要转换的对象的类型,(也获取了当前类映射的字段类型,和属性名称),然后向返回的结果中添加数据即可
3.2 查看DefaultResultSetHandler的handleResultSet方法
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) { DefaultResultHandler defaultResultHandler = new DefaultResultHandler(objectFactory);//创建默认的结果处理器 handleRowValues(rsw, resultMap, defaultResultHandler, rowBounds, null);//然后调用处理行值的方式处理获取的一行数据 multipleResults.add(defaultResultHandler.getResultList());//然后向当前的结果List集合中添加被处理后的结果对象 } else { handleRowValues(rsw, resultMap, resultHandler, rowBounds, null); } } } finally { // issue #228 (close resultsets) closeResultSet(rsw.getResultSet()); } }
发现当前的handlerResultSet方法是通过调用handleRowValues来处理获取的行的数据
3.3 查看DefaultResultSetHandler的handleRowValues方法
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); } }
3.4 查看BeanWrapper中的setBeanProperty方法
private void setBeanProperty(PropertyTokenizer prop, Object object, Object value) { try { Invoker method = metaClass.getSetInvoker(prop.getName()); Object[] params = {value}; try { method.invoke(object, params);//通过反射的方式调用set方法往对象中设置属性 } catch (Throwable t) { throw ExceptionUtil.unwrapThrowable(t); } } catch (Throwable t) { throw new ReflectionException("Could not set property '" + prop.getName() + "' of '" + object.getClass() + "' with value '" + value + "' Cause: " + t.toString(), t); } }
通过debug发现当前的
创建对象的方法其实就是
通过调用set方法来实现的(
借助反射的方式)
4.总结
1.当前的
ResultSetHandler接口就是用来处理返回的ResultSet的,通过获取需要的类型和返回的
每一行数据与整个类匹配,最后
通过反射的方式调用set方法向该对象中赋值!
以上纯属个人见解,如有问题请联系本人!
相关文章推荐
- Mybatis3源码分析(16)-Sql解析执行-结果集映射(ResultSetHandler)
- MyBatis源码解析(十)——Type类型模块之类型处理器TypeHandler
- Mybatis源码详解之接口方法被执行流程源码解析
- Mybatis源码解析-MapperRegistry注册mapper接口
- Mybatis源码分析之结果封装ResultSetHandler和DefaultResultSetHandler
- Mybatis源码分析之结果封装ResultSetHandler和DefaultResultSetHandler
- Mybatis源码分析之结果封装ResultSetHandler和DefaultResultSetHandler
- Mybatis 源码解析三、Mapper接口与mapper.xml文件绑定
- mybatis 源码分析(八)ResultSetHandler 详解
- Mybatis 源码解析二、Mapper接口的代理实现过程 MapperScannerConfigurer 解析
- MyBatis源码解析(十一)——Parsing解析模块之通用标记解析器(GenericTokenParser)与标记处理器(TokenHandler)
- Mybatis 源码解析 -- 基于配置的源码解析(二)
- Handler源码解析
- php 音悦台解析接口源码,主要是对采集视频有用
- mybatis源码之StatementHandler
- Spring源码解析 - AbstractBeanFactory 实现接口与父类分析
- MyBatis-3.4.2-源码分析11:XML解析之environmentsElement+Druid的解析准备工作:整合Druid
- springMVC源码分析--@SessionAttribute用法及原理解析SessionAttributesHandler和SessionAttributeStore
- 框架原理与源码解析: MyBatis_No2事务管理机制
- MyBatis源码解析【7】接口式编程