MyBatis 源码分析——映射结果
MyBatis最后一步一定是处理相关的结果——把数据映射成对应的模型对象。事实上在笔者看来如果读者们了解了mybatis如何去执行数据库,又是如何处理数据结果。那么就了解了mybatis的主要路线。因为不管是什么样子的ORM最终都是要执行和处理结果的。而mybatis的亮点笔者也讲了——管理sql语句。所以相对而言,处理结果就显得十分的次要。但是笔者还是希望能在这里停留一下,研究他是如何处理结果。
mybatis处理结果的代码都在DefaultResultSetHandler类里面。很抱歉的是笔者去掉了程序是如何执行到DefaultResultSetHandler类的。这里面还是希望读者们自行的去跟踪一下。DefaultResultSetHandler类的handleResultSets方法便是笔者切入的代码。事实上当代码执行到handleResultSets方法的时候,已经执行了数据库。这在PreparedStatementHandler类里面就体现出来了。如下
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
return resultSetHandler.<E> handleResultSets(ps);
}
用过mybatis的人都知道resultMap节点的作用。select节点的resultMap属性就是用来指点使用哪一个resultMap节点。而返回的结果也是用这一个节点来设置的。如下
<select id="SelectProducts" resultMap="result" >
select * from Products
where #{0} > ProductID and ProductName like #{1}
</select>
<resultMap type="com.aomi.vo.Product" id="result" autoMapping="true">
</resultMap>
所以我可以设想一下。当我们拿到了数据的时候,希望数据变成我们指定的对象模型。那么我们就必须知道是什么类型。一般来讲只要知道了什么类型就可以完成基本的映射条件。那么还会有可能出现一种希望自己去设计映射的字段和实例化对象。所以mybatis在这一方面也算是让笔者很喜欢。细详你可以查看一下官方的网站——XML映射文件。
在映射的过程中,往往我们都需要知道表的字段。所以在DefaultResultSetHandler类的handleResultSets方法里面一开始就获得了关于表的信息。表的信息都存放在ResultSetWrapper类里面。后面便就是根据这些信息来处理每一行的数据。我们还是看一下源码吧。
public List<Object> handleResultSets(Statement stmt) throws SQLException {
ErrorContext.instance().activity("handling results").object(mappedStatement.getId()); final List<Object> multipleResults = new ArrayList<Object>(); int resultSetCount = 0;
ResultSetWrapper rsw = getFirstResultSet(stmt); List<ResultMap> resultMaps = mappedStatement.getResultMaps();
int resultMapCount = resultMaps.size();
validateResultMapsCount(rsw, resultMapCount);
while (rsw != null && resultMapCount > resultSetCount) {
ResultMap resultMap = resultMaps.get(resultSetCount);
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);
}
笔者标出切入需要的俩个代码段。一个就是获得表信息的,另一个就是用于处理每一行数据的。事实上面的multipleResults变量就能说明一个问题——可能实现多个select句语的执行。所以相对的reusltMap也变成了集合类型。在XML上面就是用逗号隔开的。笔者没有做过类似这种方式的代码。笔者也是从源码中看来的。他在MapperBuilderAssistant类的getStatementResultMaps方法里面。如下。
String[] resultMapNames = resultMap.split(",");
具体情况读者们可以自己去实验一下。
在笔者看来想要理解这一部分的关键点还在是getRowValue方法这边。这里面就是我们所说的处理结果。根据reusltMap节点的信息判断出是要自己根据类型生成对象。还是要通过reusltMap节点配置信息来生成对象。然后直行获值和设值。如下。
private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap) throws SQLException {
final ResultLoaderMap lazyLoader = new ResultLoaderMap();
Object resultObject = createResultObject(rsw, resultMap, lazyLoader, null);
if (resultObject != null && !hasTypeHandlerForResultObject(rsw, resultMap.getType())) {
final MetaObject metaObject = configuration.newMetaObject(resultObject);
boolean foundValues = !resultMap.getConstructorResultMappings().isEmpty();
if (shouldApplyAutomaticMappings(resultMap, false)) {
foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, null) || foundValues;
}
foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, null) || foundValues;
foundValues = lazyLoader.size() > 0 || foundValues;
resultObject = foundValues ? resultObject : null;
return resultObject;
}
return resultObject;
}
1.createResultObject方法:根据类型和配置信息生成对象。
2.applyAutomaticMappings方法:判断是否是autoMapping="true",如果是就是自动映射赋值。
3.applyPropertyMappings方法:根据配置信息赋值。
接下来,就是各位读者们根据自己的需要进行进一步的研究了。如果想知道是如何生成对象就是去看createResultObject方法。赋值的话就去看applyAutomaticMappings方法和applyPropertyMappings方法。
MyBatis 源码分析——映射结果的更多相关文章
- MyBatis 源码分析 - 映射文件解析过程
1.简介 在上一篇文章中,我详细分析了 MyBatis 配置文件的解析过程.由于上一篇文章的篇幅比较大,加之映射文件解析过程也比较复杂的原因.所以我将映射文件解析过程的分析内容从上一篇文章中抽取出来, ...
- MyBatis 源码分析 - 插件机制
1.简介 一般情况下,开源框架都会提供插件或其他形式的拓展点,供开发者自行拓展.这样的好处是显而易见的,一是增加了框架的灵活性.二是开发者可以结合实际需求,对框架进行拓展,使其能够更好的工作.以 My ...
- MyBatis 源码分析 - 缓存原理
1.简介 在 Web 应用中,缓存是必不可少的组件.通常我们都会用 Redis 或 memcached 等缓存中间件,拦截大量奔向数据库的请求,减轻数据库压力.作为一个重要的组件,MyBatis 自然 ...
- MyBatis 源码分析 - 内置数据源
1.简介 本篇文章将向大家介绍 MyBatis 内置数据源的实现逻辑.搞懂这些数据源的实现,可使大家对数据源有更深入的认识.同时在配置这些数据源时,也会更清楚每种属性的意义和用途.因此,如果大家想知其 ...
- MyBatis 源码分析 - 配置文件解析过程
* 本文速览 由于本篇文章篇幅比较大,所以这里拿出一节对本文进行快速概括.本篇文章对 MyBatis 配置文件中常用配置的解析过程进行了较为详细的介绍和分析,包括但不限于settings,typeAl ...
- MyBatis 源码分析系列文章导读
1.本文速览 本篇文章是我为接下来的 MyBatis 源码分析系列文章写的一个导读文章.本篇文章从 MyBatis 是什么(what),为什么要使用(why),以及如何使用(how)等三个角度进行了说 ...
- 精尽MyBatis源码分析 - MyBatis初始化(二)之加载Mapper接口与XML映射文件
该系列文档是本人在学习 Mybatis 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释(Mybatis源码分析 GitHub 地址.Mybatis-Spring 源码分析 GitHub ...
- MyBatis源码分析-MyBatis初始化流程
MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简 ...
- MyBatis源码分析-SQL语句执行的完整流程
MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以对配置和原生Map使用简 ...
随机推荐
- ArcGIS制图技巧系列(3)—让地图更有立体感
ArcGIS制图技巧系列(3)-让地图更有立体感 by 李远祥 在前面的章节中,我们已经介绍过各种的地图效果,如发光效果,山体阴影效果,植被填充效果等,所有的这些效果不外乎是各种技术的叠加和技巧的使用 ...
- Visual Studio 与 Matlab实现混合编程
环境: Win10 vs2010 Matlab2015 里面有很多选做的内容,其中2.3必做 1.Matlab环境设置: (选做)我没有做这步,因为打mbuild -setup指令不识别,缺少SD ...
- 修改WebView
http://jwdev.cn/2015/09/28/use-javascript-to-delete-web-element/
- javascript学习-对象与原型
javascript学习-对象与原型 Javascript语言是符合面向对象思想的.一般来说,面向对象思想需要满足以下三个基本要求: 封装,Javascript的对象可以自由的扩充成员变量和方法,自然 ...
- <context:component-scan>详解
默认情况下,<context:component-scan>查找使用构造型(stereotype)注解所标注的类,如@Component(组件),@Service(服务),@Control ...
- linux目录结构解析
"/" :Linux文件系统的入口.也是最高一级的目录. "/bin":基本系统所需要的命令,功能和"/usr/bin"类似,这个目录下的文 ...
- BZOJ 1875: [SDOI2009]HH去散步(矩阵乘法)
首先,题意就把我们引向了矩阵乘法,注意边长m<=60,那么就按边建图,变成一个120个点的图,然后乱搞就行了。 PS:WA了N久改了3次终于A了QAQ CODE: #include<cst ...
- PHP学习2 — PHP Cookie 与 Session
PHP Cookies cookie 常用于识别用户.cookie 是服务器留在用户计算机中的小文件.每当相同的计算机通过浏览器请求页面时,它同时会发送 cookie.通过 PHP,您能够创建并取回 ...
- Log日志规范
Overview 一个在生产环境里运行的程序如果没有日志是很让维护者提心吊胆的,有太多杂乱又无意义的日志也是令人伤神.程序出现问题时候,从日志里如果发现不了问题可能的原因是很令人受挫的.本文想讨论的是 ...
- http服务搭建
http服务器搭建 主配置文件在 /etc/httpd/conf/httpd.conf 安装http yum install httpd -y 启动http服务器 systemctl start ...