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条数据。

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

至此,全部调用完毕,返回到我们自己写的业务代码处。 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/49871.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

开源大模型LLaMA 2会扮演类似Android的角色么?

在AI大模型没有商业模式&#xff1f;等文章中&#xff0c;我多次表达过这样一个观点&#xff1a;不要把大模型的未来应用方式比喻成公有云&#xff0c;大模型最终会是云端操作系统的核心&#xff08;新通用计算平台&#xff09;&#xff0c;而它的落地形式会很像过去的沃森&…

linux 指令最后一期

bc ---- linux下的计算器 bc 是一个计算器 我们输入&#xff1a;quit 来退出这个计算器 我们可以这样来用&#xff1a; uname -r uname –r指令&#xff1a; 语法&#xff1a;uname [选项] 功能&#xff1a; uname用来获取电脑和操作系统的相关信息。 补充说明&#xff1a…

数据库应用:Redis安装部署

目录 一、理论 1.缓存 2.关系型数据库与非关系型数据库 3.Redis 4.Redis安装部署 5.Redis命令工具 6.Redis数据库常用命令 7.Redis多数据库操作 二、实验 1.Redis安装部署 2.Redis命令工具 3.Redis数据库命令 4.Redis多数据库操作 三、问题 1.RESP连接CentOS 7 R…

2.playbook剧本

文章目录 playbook剧本创建剧本运行剧本定义和引用变量指定远程主机sudo切换用户when条件判断剧本格式迭代with_itemswith_listwith_flattenedwith_togetherwith_cartesianwith_nested Templates模块tags模块 playbook剧本 playbooks 本身由以下各部分组成 Tasks&#xff1a;任…

操作系统启动相关概念(BIOS、MBR、GPT、BRUB)

不管是 Windows 还是 Linux 操作系统&#xff0c;底层设备一般均为物理硬件&#xff0c;操作系统启动之前会对硬件进行检测&#xff0c;然后硬盘引导启动操作系统&#xff0c;如下为操作系统启动相关的各个概念。 一、BIOS 基本输入输出系统&#xff08;Basic Input Output Sy…

【Java】Spring——创建Spring + 对Spring的存储 /读取对象操作

文章目录 前言一、创建Spring项目二、向Spring容器中存储 Bean 对象三、从Spring容器中读取 Bean 对象得到Spring上下文对象得到 Bean 对象 总结 前言 本人是一个普通程序猿!分享一点自己的见解,如果有错误的地方欢迎各位大佬莅临指导,如果你也对编程感兴趣的话&#xff0c;互…

决策树学习

决策树学习 决策树决策树基础适用决策树学习的经典目标问题样本的表示训练样本决策树的概念发展历史 经典决策树算法ID3算法属性选择和节点混杂度&#xff08;Impurity&#xff09;ID3 Q1: 哪个属性是最佳属性&#xff1f;当前最佳属性节点选择熵&#xff08;Entropy&#xff0…

JSP 中的隐式对象预定义变量详解

JSP隐式对象是JSP容器为每个页面提供的Java对象&#xff0c;开发者可以直接使用它们而不用显式声明。JSP隐式对象也被称为预定义变量。 JSP所支持的九大隐式对象&#xff1a; request对象 request对象是javax.servlet.http.HttpServletRequest 类的示例。每当客户端请求一个J…

揭秘UniApp跨平台魔力:6道面试题带你探索!

文章目录 1. UniApp是什么&#xff1f;它有什么特点和优势&#xff1f;2. 介绍一下UniApp的跨平台原理。1. 基于WebView的渲染2. 统一封装API3. 平台特性适配4. 虚拟DOM Diff算法 3. 如何在UniApp中实现页面路由跳转&#xff1f;4. 如何在UniApp中发送网络请求&#xff1f;5. 详…

ELK 使用kibana查询和分析nginx日志

背景&#xff1a;使用kibana查询和分析nginx请求日志&#xff0c;方便开发人员查询系统日志和分析系统问题。 setp 1、定义Index patterns 2、定义Discover(Search 查询数据) 3、定义Visualizations 3.1 定义Vertical Bar 3.2 、Choose a source 3.3、定义图表 4、定义…

WPS本地镜像化在线文档操作以及样例

一个客户项目有引进在线文档操作需求&#xff0c;让我这边做一个demo调研下&#xff0c;给我的对接文档里有相关方法的说明&#xff0c;照着对接即可。但在真正对接过程中还是踩过不少坑&#xff0c;这儿对之前的对接工作做个记录。 按照习惯先来一个效果&#xff1a; Demo下载…

K8S系统监控:使用Metrics Server和Prometheus

Kubernetes 也提供了类似的linux top的命令&#xff0c;就是 kubectl top&#xff0c;不过默认情况下这个命令不会生效&#xff0c;必须要安装一个插件 Metrics Server 才可以。 Metrics Server 是一个专门用来收集 Kubernetes 核心资源指标&#xff08;metrics&#xff09;的…

qt服务器 网络聊天室

widget.cpp #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//给服务器指针实例化空间server new QTcpServer(this); }Widget::~Widget() {delete ui; }//启动…

使用Gradio构建生成式AI应用程序; Stability AI推出Stable Diffusion XL 1.0

&#x1f989; AI新闻 &#x1f680; Stability AI推出最先进的AI工具Stable Diffusion XL 1.0 摘要&#xff1a;Stability AI宣布推出Stable Diffusion XL 1.0&#xff0c;该版本是其迄今为止最先进的AI工具。Stable Diffusion XL 1.0提供更鲜艳、更准确的图片生成&#xff…

【AI之路】使用huggingface_hub优雅解决huggingface大模型下载问题

文章目录 前言一、Hugging face是什么&#xff1f;二、准备工作三、下载整个仓库或单个大模型文件1. 下载整个仓库2. 下载单个大模型文件 总结附录 前言 Hugging face 资源很不错&#xff0c;可是国内下载速度很慢&#xff0c;动则GB的大模型&#xff0c;下载很容易超时&#…

【QT 网络云盘客户端】——主窗口界面的设计

目录 1.设计主窗口界面 2.设置窗口的背景图片 3. 自定义标题栏 3.1 设置toolbutton按钮的图片 3.2 设置按钮的大小 3.3 将自定义标题栏添加设置到主页面中 3.4 去除窗口的原标题栏 3.5 设置按钮颜色 3.6 切换页面功能实现 4.我的文件页面的设计 4.1 菜单栏的设计 4…

分冶算法 剑指 07 重建二叉树 排序算法:剑指45 把数组排成最小的数 10-I 斐波那契数列

来记录几个注意事项 1.vector容器里利用find&#xff08;&#xff09;函数 不同于map&#xff08;map有find方法&#xff09;&#xff0c;vector本身是没有find这一方法&#xff0c;其find是依靠algorithm来实现的。 所以要包含头文件 #include <iostream> #include <…

物联网阀控水表计量准确度如何?

物联网阀控水表是一种新型的智能水表&#xff0c;它采用了先进的物联网技术&#xff0c;可以通过远程控制和监测水表的运行情况&#xff0c;实现更加精准的水量计量和费用结算。那么&#xff0c;物联网阀控水表的计量准确度如何呢&#xff1f;下面我们将从以下几个方面进行详细…

sql中with as用法/with-as 性能调优/with用法

文章目录 一、概述二、基本语法三、使用场景3.1、定义CTE,并为每列重命名3.2、多次引用/多次定义3.3、with与union all联合使用3.4、with返回多种结果的值3.5、with与insert使用 四、递归查询4.1、语法4.2、使用场景4.2.1、用with递归构造1-10的数据4.2.2、with与insert递归造数…

flink to starrocks 问题集锦....

[问题排查]导入失败相关 - 问题排查 - StarRocks中文社区论坛 starrocks官网如下&#xff1a; Search StarRocks Docs starrocks内存配置项&#xff1a; 管理内存 Memory_management StarRocks Docs 问题1&#xff1a;实时写入starrocks &#xff0c;配置参数设置如下&a…