当前位置: 首页 > news >正文

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 方法根据映射规则&#xff08;resultMap&#xff09;对结果集进行转化…...

Unittest加载执行用例的方法总结

前言 说到测试框架&#xff0c;unittest是我最先接触的自动化测试框架之一了&#xff0c; 而且也是用的时间最长的&#xff0c; unittest框架有很多方法加载用例&#xff0c;让我们针对不同的项目&#xff0c;不同项目的大小及用例的多少自己选择加载方式。今天我们就简单的说说…...

使用预训练的2D扩散模型改进3D成像

扩散模型已经成为一种新的生成高质量样本的生成模型&#xff0c;也被作为有效的逆问题求解器。然而&#xff0c;由于生成过程仍然处于相同的高维&#xff08;即与数据维相同&#xff09;空间中&#xff0c;极高的内存和计算成本导致模型尚未扩展到3D逆问题。在本文中&#xff0…...

微服务测试是什么?

微服务测试是一种特殊的测试类型&#xff0c;因为它涉及到多个独立的服务。以下是进行微服务测试的一般性步骤&#xff1a; 【B站最通俗易懂】Python接口自动化测试从入门到精通&#xff0c;超详细的进阶教程&#xff0c;看完这套视频就够了 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 插入总结&#xff1a; 四、插入操作源码 五、红黑树验证 一、红黑树概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff0…...

教育机构视频播放时观看行为分析有哪些应用?

教育机构视频播放时观看行为分析有哪些应用&#xff1f; 观看行为分析 观看行为分析是指我们平台基于视频大数据分析&#xff0c;能够以秒为粒度展示观众如何观看您的视频。 视频观看热力图是单次观看行为的图形化表示&#xff0c;我们平台云点播视频的每一次播放&#xff0…...

Jmeter+验证json结果是否正确小技巧

前言&#xff1a; 通过sql语句或者返回的参数&#xff0c;可以在查看结果树返回的结果中&#xff0c;用方法先跑一下验证是否取到自己想要的值 步骤&#xff1a; 1、添加查看结果树 2、跑出结果 3、在查看结果树中 text改成选Json Path Tester 返回的值如果是列表里面的字符…...

Spring 6.0官方文档示例(22): singleton类型的bean和prototype类型的bean协同工作的方法(一)

一、配置文件&#xff1a; <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的应用场景非常广泛&#xff0c;如公共安全、交通管理、企业安全、教育、医疗等众多领域&#xff0c;细分场景可用于如执法记录仪、智能安全帽、智能监控、智慧零售、智慧教育、远程办公、明厨亮灶、智慧交通、智慧工地、雪亮工程、平安乡村、生产运输、车载终…...

el-Cascader 中div上绑定keyDown事件

keydown&#xff0c;keyup&#xff0c;keypress 事件默认是给页面上可以聚焦的元素绑定键盘事件&#xff0c;例如input输入框&#xff0c;点击输入框即代表聚焦在该元素上。那么想要给div或者其他不能聚焦的元素上使用键盘事件怎么处理呢&#xff1f;这里用到tabindex属性。 …...

elementUI 表格滚动分页加载请求数据

需求&#xff1a;elementui Table表格滚动分页&#xff08;不使用分页组件&#xff09;&#xff0c;请求数据。 1、自定义加载更多数据的指令&#xff0c;在utils文件夹中创建 loadMore.js /*** 加载更多数据的指令*/ export default {install(Vue) {Vue.mixin({directives: …...

JAVA面试总结-Redis篇章(五)——持久化

Java面试总结-Redis篇章&#xff08;五&#xff09;——持久化 1.RDBRDB全称Redis Database Backup file (Redis数据备份文件)&#xff0c;也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故障重启后&#xff0c;从磁盘读取快照文件&#x…...

【数据结构】·顺序表函数实现·赶紧学起来呀

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …...

C++,类和对象-多态,制作饮品

#include<iostream> using namespace std;//多态案例&#xff0c;制作饮品class AbstractDrinking { public://煮水virtual void Boil() 0;//冲泡virtual void Brew() 0;//倒入茶杯virtual void PourInCup() 0;//加入辅料virtual void PutSomething() 0;//制作饮品vo…...

网站分析:学习如何分析目标网站的页面结构和URL规律,确定爬取目标和策略。

要学习如何分析目标网站的页面结构和URL规律&#xff0c;确定爬取目标和策略&#xff0c;可以遵循以下步骤&#xff1a; 目标网站的页面结构分析&#xff1a; 寻找目标网站的主页&#xff0c;并观察主页上的链接、导航菜单和内容分类等元素&#xff0c;以了解网站的整体结构。 …...

《向量数据库指南》:向量数据库Pinecone如何集成数据湖

目录 为什么选择Databricks? 为什么选择Pinecone? 设置Spark集群 环境设置 将数据集加载到分区中 创建将文本转换为嵌入的函数 将UDF应用于数据 更新嵌入 摘要 使用Databricks和Pinecone在规模上创建和索引向量嵌入 建立在Apache Spark之上的Databricks是一个强大的…...

Vue3中使用pinia

在Vue 3中使用Pinia&#xff0c;您需要按照以下步骤进行设置&#xff1a; 安装Pinia&#xff1a; npm install pinia创建和配置Pinia存储&#xff1a; // main.jsimport { createApp } from vue import { createPinia } from pinia import App from ./App.vueconst app create…...

Mysql中(@i:=@i+1)的介绍

i:i1 表达式 生成伪列实现自增序列 语法&#xff1a; select (i:i1) as ,t.* from table_name t,(select i:0) as j (i:i1)代表定义一个变量&#xff0c;每次叠加 1&#xff1b; (select i:0) as j 代表建立一个临时表&#xff0c;j是随便取的表名&#xff0c;但别名一定…...

Nexperia和KYOCERA AVX Components Salzburg 就车规氮化镓功率模块达成合作

Nexperia和KYOCERA AVX Components Salzburg 就车规氮化镓功率模块达成合作 基础半导体器件领域的高产能生产专家Nexperia&#xff08;安世半导体&#xff09;近日宣布与国际著名的为汽车行业提供先进电子器件的供应商 KYOCERA AVX Components (Salzburg) GmbH 建立合作关系&am…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路

进入2025年以来&#xff0c;尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断&#xff0c;但全球市场热度依然高涨&#xff0c;入局者持续增加。 以国内市场为例&#xff0c;天眼查专业版数据显示&#xff0c;截至5月底&#xff0c;我国现存在业、存续状态的机器人相关企…...

MVC 数据库

MVC 数据库 引言 在软件开发领域,Model-View-Controller(MVC)是一种流行的软件架构模式,它将应用程序分为三个核心组件:模型(Model)、视图(View)和控制器(Controller)。这种模式有助于提高代码的可维护性和可扩展性。本文将深入探讨MVC架构与数据库之间的关系,以…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机&#xff08;无人驾驶飞行器&#xff0c;UAV&#xff09;技术的快速发展&#xff0c;其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统&#xff0c;无人机的“黑飞”&…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景

Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知&#xff0c;帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量&#xff0c;能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度&#xff0c;还为机器人、医疗设备和制造业的智…...

算术操作符与类型转换:从基础到精通

目录 前言&#xff1a;从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符&#xff1a;、-、*、/、% 赋值操作符&#xff1a;和复合赋值 单⽬操作符&#xff1a;、--、、- 前言&#xff1a;从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...

[USACO23FEB] Bakery S

题目描述 Bessie 开了一家面包店! 在她的面包店里&#xff0c;Bessie 有一个烤箱&#xff0c;可以在 t C t_C tC​ 的时间内生产一块饼干或在 t M t_M tM​ 单位时间内生产一块松糕。 ( 1 ≤ t C , t M ≤ 10 9 ) (1 \le t_C,t_M \le 10^9) (1≤tC​,tM​≤109)。由于空间…...