MyBatis源码分析_ResultSetHandler(7)
目录
1. 传统JDBC
2. Mybatis访问数据库
2.1 Statement访问数据库
2.2 火枪手 ResultSetHandler 出现
3. ResultSetHandler处理结果集
3.1 首先就是进入 handleResultSets 方法
3.2 handleResultSet 方法根据映射规则(resultMap)对结果集进行转化
3.3 handleRowValuesForSimpleResultMap 方法对行进行映射处理
4. getRowValue方法针对读取ResultSet对象进行映射(3.3细化)
4.1 根据resultMap的type属性,实例化目标对象
4.2 对目标对象进行封装得到metaObjcect,为后续的赋值操作做好准备
4.3一般情况下 autoMappingBehavior默认值为PARTIAL,对未明确指定映射规则的字段进行自动映射
4.4 映射resultMap中明确指定需要映射的列
4.5 如果没有一个映射成功的属性,则根据的配置返回null或者结果对象
5. 保存映射结果对象
5.1 resultContext 计数作用
5.2 ResultHandler存储结果集
6. 主流程over
1. 传统JDBC
Mybatis其实就是封装传统JDBC的,它和传统JDBC访问数据库基本一模一样。因此,不要觉得Mybatis有多高级。而 ResultSetHandler 就是处理我们JDBC访问数据库获取到的ResultSet结果集的。在此之前,我们还是先看一下传统JDBC:

再次基础之上,我们继续分析Mybatis是如何访问数据库并且封装对象的。
2. Mybatis访问数据库

中间涉及到设置参数,初始化Statement等操作,这些在MyBatis源码分析_Executor组件及3个火枪手(6)_chen_yao_kerr的博客-CSDN博客已经 分析过了。接下来将是直接分析访问数据库以及返回结果集的处理。



最终,他会调用到 RoutingStatementHandler的query方法。而我们在实例化RoutingStatementHandler的时候,我们说过它是典型的策略模式。它是根据xml配置文件的信息,生成不同的StatementHandler对象,而本文则是基于PreparedStamentHandler进行的,因此它必然会进入PreparedStamentHandler的query方法:


2.1 Statement访问数据库

最终调用的是mysql的底层jar包PreparedStatementLogger对象访问的数据库,这一点和JDBC访问的方式一模一样,我们就不做过多的分析了。

2.2 火枪手 ResultSetHandler 出现
访问数据库结束以后,我们会对调用ResultSetHandler对象对结果集进行mybatis特有的处理,这一点是和JDBC不同的:

而 StatementHandler 的基类中,是持有ResultSetHandler的:

所有,我们的PreparedStatementHandler才可以直接使用ResultSetHandler对象处理结果集ResultSet.
3. ResultSetHandler处理结果集
3.1 首先就是进入 handleResultSets 方法
a. 首先就是从Statement对象中获取第一个结果集ResultSet并包装成 ResultSetWrapper
b. 获取结果集对应的ResultMap,这个是在第一阶段加载xml文件的时候就准备好的,column-property的形式
c. 根据映射规则(resultMap)对结果集进行转化,转换成目标对象以后放入multipleResults中

d. 获取下一个结果集继续遍历,直到遍历完所有的结果集位置。
3.2 handleResultSet 方法根据映射规则(resultMap)对结果集进行转化
其实,这个方法就是对结果集进行缓存处理,并且在填充完以后放入list中。


3.3 handleRowValuesForSimpleResultMap 方法对行进行映射处理

针对读取ResultSet对象进行映射并且保存映射结果,我将单独开一个大的段落进行分析。本篇后面的所有内容都是针对此处进行详细分析。
4. getRowValue方法针对读取ResultSet对象进行映射(3.3细化)
首先看一下getRowValue方法的总体结构,后面将针对这个结果逐步分析每一步都干了什么事情

4.1 根据resultMap的type属性,实例化目标对象
这一步挺简单的,就是根据我们配置的返回值类型,实例化出来一个空的对象,方便后面的步骤进行值的设置

4.2 对目标对象进行封装得到metaObjcect,为后续的赋值操作做好准备
元数据对象,由Configuration对象负责生成,它是mybatis提供的反射工具类。因为这是一个底层代码,使用反射设置属性值是通用做法,而传统的java反射对处理List、Map、嵌套类等处理起来并不方便。而Mybatis提供的MetaObject对象,能够很好的处理集合、嵌套类等,功能更为强大。

生成对象以后,我们来看一下这个结构:

由于我们的测试case不涉及嵌套类型的查询,因此无法看到嵌套类型具体值的设置过程,后面会补一篇关于嵌套类型的博客,单独进行分析。
4.3一般情况下 autoMappingBehavior默认值为PARTIAL,对未明确指定映射规则的字段进行自动映射

由于我们是使用最简单的类型进行查询的,所以我们会把select语句中查询的字段进行自动映射。简单点说就是默认查询的字段 和 表中的字段名是一模一样的,这届根据当前的查询字段进行设置值就ok了。

而值的查询,就是和传统的JDBC代码一样,从ResultSet中获取并设置到目标对象中的:

可能有人会说,怎么是把值设置到了metaObject元数据中了呢? 其实,元数据中之前提过了,是会生成BeanWrapper对象的,这就是一个Bean对象。我们最终是通过反射,设置到这个bean对象中的:

4.4 映射resultMap中明确指定需要映射的列
这一章节,是我们在xml文件中配置了ResultMap的映射关系,按照映射关系进行设置值的,逻辑与4.3雷同
4.5 如果没有一个映射成功的属性,则根据<returnInstanceForEmptyRow>的配置返回null或者结果对象
这一步就没有什么好说的了, rowValue = foundValues || configuration.isReturnInstanceForEmptyRow() ? rowValue : null;
5. 保存映射结果对象

其实,大部分的映射都是放置在 resultHandler 和 resultContext中的。

5.1 resultContext 计数作用

5.2 ResultHandler存储结果集

也就是说,能够获取到ResultHandler对象,就可以获取到封装好了的所有结果集了。
6. 主流程over
待我们获取到ResultHandler对象以后,就可以从ResultHandler对象中获取到所有的结果集,并放入名称为multipleResults的List中。

然后就是一路返回List到Executor组件中;
接着返回,因为我们查询调用的是SqlSession中的 selectOne 方法,所有只会返回1条数据。

而调用的入口方法在此处:

至此,全部调用完毕,返回到我们自己写的业务代码处。
相关文章:
MyBatis源码分析_ResultSetHandler(7)
目录 1. 传统JDBC 2. Mybatis访问数据库 2.1 Statement访问数据库 2.2 火枪手 ResultSetHandler 出现 3. ResultSetHandler处理结果集 3.1 首先就是进入 handleResultSets 方法 3.2 handleResultSet 方法根据映射规则(resultMap)对结果集进行转化…...
Unittest加载执行用例的方法总结
前言 说到测试框架,unittest是我最先接触的自动化测试框架之一了, 而且也是用的时间最长的, unittest框架有很多方法加载用例,让我们针对不同的项目,不同项目的大小及用例的多少自己选择加载方式。今天我们就简单的说说…...
使用预训练的2D扩散模型改进3D成像
扩散模型已经成为一种新的生成高质量样本的生成模型,也被作为有效的逆问题求解器。然而,由于生成过程仍然处于相同的高维(即与数据维相同)空间中,极高的内存和计算成本导致模型尚未扩展到3D逆问题。在本文中࿰…...
微服务测试是什么?
微服务测试是一种特殊的测试类型,因为它涉及到多个独立的服务。以下是进行微服务测试的一般性步骤: 【B站最通俗易懂】Python接口自动化测试从入门到精通,超详细的进阶教程,看完这套视频就够了 1. 确定系统架构 了解微服务架构对…...
《现代C++教程》笔记(5-7)
文章目录 5 智能指针与内存管理5.1 RAII与引用计数5.2 std::shared_ptr5.3 std::unique_ptr5.4 std::weak_ptr 6 正则表达式7 并行与并发7.1 并行基础7.2 互斥量与临界区7.3 期物7.4 条件变量7.5 原子操作与内存模型 5 智能指针与内存管理 5.1 RAII与引用计数 在传统 C 中&am…...
红黑树深入剖析【C++】
目录 一、红黑树概念 二、红黑树节点结构设计 三、插入操作 处理情况1 处理情况2 处理情况3 插入总结: 四、插入操作源码 五、红黑树验证 一、红黑树概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色࿰…...
教育机构视频播放时观看行为分析有哪些应用?
教育机构视频播放时观看行为分析有哪些应用? 观看行为分析 观看行为分析是指我们平台基于视频大数据分析,能够以秒为粒度展示观众如何观看您的视频。 视频观看热力图是单次观看行为的图形化表示,我们平台云点播视频的每一次播放࿰…...
Jmeter+验证json结果是否正确小技巧
前言: 通过sql语句或者返回的参数,可以在查看结果树返回的结果中,用方法先跑一下验证是否取到自己想要的值 步骤: 1、添加查看结果树 2、跑出结果 3、在查看结果树中 text改成选Json Path Tester 返回的值如果是列表里面的字符…...
Spring 6.0官方文档示例(22): singleton类型的bean和prototype类型的bean协同工作的方法(一)
一、配置文件: <beans xmlns"http://www.springframework.org/schema/beans"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xmlns:context"http://www.springframework.org/schema/context"xsi:schemaLocation"http…...
Android平台GB28181设备接入侧如何同时对外输出RTSP流?
技术背景 GB28181的应用场景非常广泛,如公共安全、交通管理、企业安全、教育、医疗等众多领域,细分场景可用于如执法记录仪、智能安全帽、智能监控、智慧零售、智慧教育、远程办公、明厨亮灶、智慧交通、智慧工地、雪亮工程、平安乡村、生产运输、车载终…...
el-Cascader 中div上绑定keyDown事件
keydown,keyup,keypress 事件默认是给页面上可以聚焦的元素绑定键盘事件,例如input输入框,点击输入框即代表聚焦在该元素上。那么想要给div或者其他不能聚焦的元素上使用键盘事件怎么处理呢?这里用到tabindex属性。 …...
elementUI 表格滚动分页加载请求数据
需求:elementui Table表格滚动分页(不使用分页组件),请求数据。 1、自定义加载更多数据的指令,在utils文件夹中创建 loadMore.js /*** 加载更多数据的指令*/ export default {install(Vue) {Vue.mixin({directives: …...
JAVA面试总结-Redis篇章(五)——持久化
Java面试总结-Redis篇章(五)——持久化 1.RDBRDB全称Redis Database Backup file (Redis数据备份文件),也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后,从磁盘读取快照文件&#x…...
【数据结构】·顺序表函数实现·赶紧学起来呀
💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤 📃个人主页 :阿然成长日记 …...
C++,类和对象-多态,制作饮品
#include<iostream> using namespace std;//多态案例,制作饮品class AbstractDrinking { public://煮水virtual void Boil() 0;//冲泡virtual void Brew() 0;//倒入茶杯virtual void PourInCup() 0;//加入辅料virtual void PutSomething() 0;//制作饮品vo…...
网站分析:学习如何分析目标网站的页面结构和URL规律,确定爬取目标和策略。
要学习如何分析目标网站的页面结构和URL规律,确定爬取目标和策略,可以遵循以下步骤: 目标网站的页面结构分析: 寻找目标网站的主页,并观察主页上的链接、导航菜单和内容分类等元素,以了解网站的整体结构。 …...
《向量数据库指南》:向量数据库Pinecone如何集成数据湖
目录 为什么选择Databricks? 为什么选择Pinecone? 设置Spark集群 环境设置 将数据集加载到分区中 创建将文本转换为嵌入的函数 将UDF应用于数据 更新嵌入 摘要 使用Databricks和Pinecone在规模上创建和索引向量嵌入 建立在Apache Spark之上的Databricks是一个强大的…...
Vue3中使用pinia
在Vue 3中使用Pinia,您需要按照以下步骤进行设置: 安装Pinia: npm install pinia创建和配置Pinia存储: // main.jsimport { createApp } from vue import { createPinia } from pinia import App from ./App.vueconst app create…...
Mysql中(@i:=@i+1)的介绍
i:i1 表达式 生成伪列实现自增序列 语法: select (i:i1) as ,t.* from table_name t,(select i:0) as j (i:i1)代表定义一个变量,每次叠加 1; (select i:0) as j 代表建立一个临时表,j是随便取的表名,但别名一定…...
Nexperia和KYOCERA AVX Components Salzburg 就车规氮化镓功率模块达成合作
Nexperia和KYOCERA AVX Components Salzburg 就车规氮化镓功率模块达成合作 基础半导体器件领域的高产能生产专家Nexperia(安世半导体)近日宣布与国际著名的为汽车行业提供先进电子器件的供应商 KYOCERA AVX Components (Salzburg) GmbH 建立合作关系&am…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...
从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...
让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
LOOI机器人的技术实现解析:从手势识别到边缘检测
LOOI机器人作为一款创新的AI硬件产品,通过将智能手机转变为具有情感交互能力的桌面机器人,展示了前沿AI技术与传统硬件设计的完美结合。作为AI与玩具领域的专家,我将全面解析LOOI的技术实现架构,特别是其手势识别、物体识别和环境…...
协议转换利器,profinet转ethercat网关的两大派系,各有千秋
随着工业以太网的发展,其高效、便捷、协议开放、易于冗余等诸多优点,被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口,具有实时性、开放性,使用TCP/IP和IT标准,符合基于工业以太网的…...
AxureRP-Pro-Beta-Setup_114413.exe (6.0.0.2887)
Name:3ddown Serial:FiCGEezgdGoYILo8U/2MFyCWj0jZoJc/sziRRj2/ENvtEq7w1RH97k5MWctqVHA 注册用户名:Axure 序列号:8t3Yk/zu4cX601/seX6wBZgYRVj/lkC2PICCdO4sFKCCLx8mcCnccoylVb40lP...
