Mybatis入门源码二:sql执行

后面开始分析sql执行的源码流程
也就是这一部分
image.png

一、factory.openSession()

image.png
image.png
重点关注configuration.newExecutor这个方法,获取事务处理器比较简单,就是获取一个jdbc的事务管理器。
image.png

  1. 这个方法通过传入的执行器类型来创建不同的执行器,有simple、batch、reuse等
  2. 如果支持缓存的话,会创建CachingExecutor执行器

执行完成之后最后生成了一个DefaultSqlSession,有关DefaultSqlSession,特别要注意一点,它是一个非线程安全的类。
image.png

二、获取mapper接口

image.png
image.png
image.png
image.png
关于knownMappers前面讲过:是一个map,里面存放的是mapper的类型和MapperProxyFactory类。
image.png

后面就是调用mapperProxyFactory.newInstance(sqlSession)进行mapper接口的实例化。
image.png
最终会拿着mapper接口、代理方法缓存 生成InvokeHandler(用来生成Jdk代理必须要的类,当调用被代理的方法的时候,会调用到InvokeHandler的invokde方法)
最终返回的代理对象就是下图所示:
image.png

三、处理查询操作

image.png
当我们调用这个查询方法的时候,最终会调用到userProxy的invoke方法
image.png
先看cachedInvoker方法,
image.png
最终会生成一个PlainMethodInvoker,这个类是MapperProxy的静态内部类
image.png
这里会调用到mapperMethod.execute方法, MapperMethod中,command存放的是sql的一些信息,method存放方法的一些信息
image.png

public class MapperMethod {// todo 存放sql的一些信息,其中name属性存放的是“包名、类名、方法名”private final SqlCommand command;// todo 方法的签名,主要存放方法的一些信息private final MethodSignature method;public MapperMethod(Class<?> mapperInterface, Method method, Configuration config) {this.command = new SqlCommand(config, mapperInterface, method);this.method = new MethodSignature(config, mapperInterface, method);}public Object execute(SqlSession sqlSession, Object[] args) {Object result;switch (command.getType()) {case INSERT: {Object param = method.convertArgsToSqlCommandParam(args);result = rowCountResult(sqlSession.insert(command.getName(), param));break;}case UPDATE: {Object param = method.convertArgsToSqlCommandParam(args);result = rowCountResult(sqlSession.update(command.getName(), param));break;}case DELETE: {Object param = method.convertArgsToSqlCommandParam(args);result = rowCountResult(sqlSession.delete(command.getName(), param));break;}case SELECT:// todo 处理查询操作if (method.returnsVoid() && method.hasResultHandler()) {executeWithResultHandler(sqlSession, args);result = null;} else if (method.returnsMany()) {// todo 返回多行记录result = executeForMany(sqlSession, args);} else if (method.returnsMap()) {result = executeForMap(sqlSession, args);} else if (method.returnsCursor()) {result = executeForCursor(sqlSession, args);} else {Object param = method.convertArgsToSqlCommandParam(args);result = sqlSession.selectOne(command.getName(), param);if (method.returnsOptional()&& (result == null || !method.getReturnType().equals(result.getClass()))) {result = Optional.ofNullable(result);}}break;case FLUSH:result = sqlSession.flushStatements();break;default:throw new BindingException("Unknown execution method for: " + command.getName());}if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {throw new BindingException("Mapper method '" + command.getName()+ " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");}return result;}

在execute方法里面,会处理 sql 的 INSERT(mapper.xml 中的 insert 标签)、UPDATE(mapper.xml 中的 update 标签)、DELETE(mapper.xml 中的 delete 标签)、SELECT(mapper.xml 中的 select 标签)、FLUSH(针对 BatchExecutor 执行器,执行缓存的 Statement)等操作,这里我们仅关注 select 操作
image.png
image.png
接下来调用DefaultSqlSession.selectList方法来执行
image.png
这里会从configuration里面通过接口对应的MappedStatement,通过执行器调用执行,由于我们默认设置了一级缓存,所以会执行到CacheingExecutor.query方法
image.png
image.png
这个delegate.query最终调用的是SimpleExecutor.query方法
image.png
image.png
最终会执行到simpleExecutor.doQuery方法
image.png

四、总结

本文主要介绍了 mybatis 执行 sql 的流程,介绍的内容如下:

  1. mybatis 的 sql 执行操作方法在 SqlSession 中,SqlSession 是 mybatis 的执行入口
  2. XxxMapper 是一个接口,mybatis 基于 jdk 动态代理机制会生成一个代理对象,其 InvocationHandler(具体类为 MapperProxy)的 invoker(…) 方法会获取 mapper.xml 定义的 sql 并执行
  3. 执行 XxxMapper 方法时,实际调用的是 MapperProxy#invoker(…) 方法,整个方法的执行过程中,会获取 mapper.xml 中的 sql 语句,然后使用执行器(SimpleExecutor、ReuseExecutor、BatchExecutor 等)处理 sql 的执行
  4. mybatis 提供的 DefaultSqlSession 是非线程安全的,想要线程安全,可以使用 SqlSessionManager

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CNN——ResNet

深度残差网络&#xff08;Deep residual network, ResNet&#xff09;的提出是CNN图像史上的一件里程碑事件&#xff0c;并且让深度学习真正可以继续做下去&#xff0c;斩获2016 CVPR Best Paper。此外ResNet的作者都是中国人&#xff0c;一作何恺明。ResNet被提出以后很多的网…

Vue3+Pinia实现持久化动态主题切换

PC端主题切换大家都用过&#xff0c;下面用Vue3Pinia实现一下这个过程; 【源码地址】 1、准备工作 npm install pinia npm install pinia-plugin-persist2、基础配置 // main.js import { createApp } from vue import App from ./App.vue import bootstrap from "../bo…

红日靶场 4

靶场配置 ​ 733 x 668899 x 819 ​ ​ 733 x 6161466 x 1232 ​ ​ 733 x 6261449 x 1237 ​ ​ 733 x 6301450 x 1247 ​ IP 地址分配&#xff1a; Win7: 192.168.183.133(内网)Ubuntu: 192.168.183.134(内网) 192.168.120.137(外网)DC: 192.168.183.130(内网)Kali…

Python综合数据分析_根据订单求RFM值

文章目录 0.导入数据1.数据可视化2.数据清洗3.特征工程4.构建User用户表5.求R值6.求F值7.求M值 0.导入数据 import pandas as pd #导入Pandas df_sales pd.read_csv(订单.csv) #载入数据 df_sales.head() #显示头几行数据 1.数据可视化 import matplotlib.pyplot as plt #导…

js逆向第13例:猿人学第6题js混淆-回溯赛

文章目录 m是加密字符串怎么来的?浏览器环境检测本地运行的js代码任务六:采集全部5页的彩票数据,计算全部中奖的总金额(包含一、二、三等奖) 此题总体难度低于第5题,老规矩还是查看控制台请求地址https://match.yuanrenxue.cn/api/match/6?m=rPRDgpbV3Wd%252FyPfURQAkxK…

使用Vite创建vue3工程

介绍 使用Vite构建工具&#xff0c;创建Vue3工程 示例 第一步&#xff1a;执行创建项目的命令&#xff0c;study-front-vue3是项目名称 npm init vite-app study-front-vue3第二步&#xff1a;进入项目文件夹&#xff0c;执行命令&#xff0c;安装模块 cd study-front-vue…

使用qtquick调用python程序,pytorch

一. 内容简介 使用qtquick调用python程序 二. 软件环境 2.1vsCode 2.2Anaconda version: conda 22.9.0 2.3pytorch 安装pytorch(http://t.csdnimg.cn/GVP23) 2.4QT 5.14.1 新版QT6.4,&#xff0c;6.5在线安装经常失败&#xff0c;而5.9版本又无法编译64位程序&#xf…

程序员为什么不能一次把功能写好,是因为他不想吗

引言 交流一下为什么他做的功能这么多Bug 大家好&#xff0c;最近看到一个有趣的问题&#xff1a; 程序员为什么要不能一次性写好&#xff0c;需要一直改Bug&#xff1f; 在我看来&#xff0c;程序员也是人&#xff0c;并非机器。 拿这个问题去质问程序员&#xff0c;答案无…

Java学习,一文掌握Java之SpringBoot框架学习文集(3)

&#x1f3c6;作者简介&#xff0c;普修罗双战士&#xff0c;一直追求不断学习和成长&#xff0c;在技术的道路上持续探索和实践。 &#x1f3c6;多年互联网行业从业经验&#xff0c;历任核心研发工程师&#xff0c;项目技术负责人。 &#x1f389;欢迎 &#x1f44d;点赞✍评论…

【网络】网络层协议ARP和IP协议转发流程

目录 一、IP概述 1.1 IP简介 1.2 IP协议 二、IP地址与硬件地址 三、地址解析协议ARP 3.1 ARP协议简介 3.2 ARP工作流程 3.3 ARP的四种典型情况 四、IP协议的转发流 一、IP概述 1.1 IP简介 IP地址&#xff08;Internet Protocol Address&#xff09;是指互联网协议地址…

[VUE]1-创建vue工程

目录 基于脚手架创建前端工程 1、环境要求 2、操作过程 3、工程结构 4、启动前端服务 &#x1f343;作者介绍&#xff1a;双非本科大三网络工程专业在读&#xff0c;阿里云专家博主&#xff0c;专注于Java领域学习&#xff0c;擅长web应用开发、数据结构和算法&#xff0c…

如何写html邮件 —— 参考主流outook、gmail、qq邮箱渲染邮件过程

文章目录 ⭐前言⭐outlook渲染邮件⭐gmail邮箱渲染邮件⭐qq邮箱渲染邮件 ⭐编写html邮件&#x1f496;table表格的属性&#x1f496;文本&#x1f496;图片&#x1f496;按钮&#x1f496;背景图片 ⭐总结⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于 …

云卷云舒:【实战篇】对象存储迁移

云卷云舒&#xff1a;【实战篇】MySQL迁移-CSDN博客 1. 简介 对象存储与块存储、文件存储并列为云计算三大存储模型。提供海量存储空间服务&#xff0c;具备快速的数据存取性能、高可靠和数据安全性&#xff0c;通过标准的RESTful API接口和丰富的SDK包来提供服务&#xff0c…

3D模型UV展开原理

今年早些时候&#xff0c;我为 MAKE 杂志写了一篇教程&#xff0c;介绍如何制作视频游戏角色的毛绒动物。 该技术采用给定的角色 3D 模型及其纹理&#xff0c;并以编程方式生成缝纫图案。 虽然我已经编写了一般摘要并将源代码上传到 GitHub&#xff0c;但我在这里编写了对使这一…

Presto CLI学习

1. 序言 作为Presto的客户端之一&#xff0c;Presto CLI是一个基于终端的交互式shell&#xff0c;对应presto源码中的presto-cli模块 Presto CLI的本质是一个self-executing jar —— presto-cli-version-executable.jar&#xff0c;就像一个普通的UNIX可执行文件 因此&#…

olap/spark-tungsten:codegen

15721这一章没什么好说的&#xff0c;不再贴课程内容了。codegen和simd在工业界一般只会选一种实现。比如phothon之前用codegen&#xff0c;然后改成了向量化引擎。一般gen的都是weld IR/LLVM IR/当前语言&#xff0c;gen成C的也要检查是不是有本地预编译版本&#xff0c;要不没…

城市建设模拟游戏:鼠托邦 RATOPIA 中文免安装版

《鼠托邦》是一款由独立游戏开发团队Cassel Games开发的基地建设模拟游戏。在游戏中&#xff0c;玩家需要管理一个庞大的地下鼠国&#xff0c;打造理想中的“鼠托邦”。玩家可以化身为糖果派对游戏中的老鼠女王&#xff0c;带领老鼠民众建设城市、勘探地下领域以扩展生存空间。…

Web前端-JavaScript(ES6)

文章目录 1.ES5数组新方法1.1 数组方法forEach遍历数组1.2 数组方法filter过滤数组1.3 数组方法some1.4 some和forEach和filter的区别1.5 find()1.6 findIndex()1.7 trim去除字符串两端的空格1.8 获取对象的属性名1.9 Object.defineProperty 2.ES6语法2.1 ES6概述2.2 为什么使用…

CTF数据分析题详解

目录 题目一(1.pcap) 题目二(2.pcap) 题目三(3.pcap) 题目四(4.pcap) CTF流量分析经典例题详解-CSDN博客 本文章涉及的所有题目附件下载地址&#xff1a; 链接&#xff1a; https://pan.baidu.com/s/18mWo5vn1zp_XbmcQrMOKRA 提取码&#xff1a;hrc4 声明&#xff1a;这里…

WorkPlus AI助理为企业提供智能客服的机器人解决方案

在数字化时代&#xff0c;企业面临着客户服务的重要挑战。AI客服机器人成为了提升客户体验和提高工作效率的关键工具。作为一款优秀的AI助理&#xff0c;WorkPlus AI助理以其智能化的特点和卓越的功能&#xff0c;为企业提供了全新的客服机器人解决方案。 为什么选择WorkPlus A…