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.mfbz.cn/a/300779.html

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

相关文章

x-cmd pkg | trdsql - 能对 CSV、LTSV、JSON 和 TBLN 执行 SQL 查询的工具

目录 简介首次用户技术特点竞品和相关作品进一步阅读 简介 trdsql 是一个使用 sql 作为 DSL 的强大工具: 采用 SQL 对 CSV、LTSV、JSON 和 TBLN 文件执行查询与 MySQL&#xff0c;Postgresql&#xff0c;Sqlite 的 Driver 协同&#xff0c;可以实现对应数据库的表与文件的 JO…

安全基础~信息搜集3

文章目录 知识补充APP信息搜集php开发学习理解漏洞 知识补充 端口渗透总结 python Crypto报错&#xff1a;https://blog.csdn.net/five3/article/details/86160683 APP信息搜集 1. AppInfoScanner 移动端(Android、iOS、WEB、H5、静态网站)信息收集扫描工具 使用教程 演示&…

超维空间M1无人机使用说明书——21、基于opencv的人脸识别

引言&#xff1a;M1型号无人机不仅提供了yolo进行物体识别&#xff0c;也增加了基于opencv的人脸识别功能包&#xff0c;仅需要启动摄像头和识别节点即可 链接: 源码链接 一、一键启动摄像头和人脸识别节点 roslaunch robot_bringup bringup_face_detect.launch无报错&#…

解决ImportError: Failed to import test module: sys.__init__

解决ImportError: Failed to import test module: sys.init 背景 学习通过文件夹执行测试脚本时&#xff0c;出现了错误&#xff1a;ImportError: Failed to import test module: sys.__init__ 解决过程 根据报错信息&#xff1a;sys is not a package大胆猜测可能是文件名…

爬虫-1-请求和响应

#无以规矩&#xff0c;不成方圆(&#xff89;_ _)&#xff89; <(_ _)> 请求和响应 案例实现

STLink下不了程序的解决办法

目录 1.检查物理接线是否正确 2.检查工程中用的引脚与这两个引脚是否有冲突 3.其次查看HAL_MspInit函数中是否使能SWJ 1.检查物理接线是否正确 2.检查工程中用的引脚与这两个引脚是否有冲突 stm32 swdio和swdclk引脚分别与stm32的PA13&#xff0c;PA14引脚相连 3.其次查看HA…

C++模板——(1)模板的概念

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 创造机会的人是勇者&#xff0c;等待机…

构建网络信息安全的中国方案 - 国密SSL协议介绍以及国密Nginx服务器部署

国密SSL协议 国密SSL协议指的是采用国密算法&#xff0c;符合国密标准的安全传输协议。简而言之&#xff0c;国密SSL就是SSL/TLS协议的国密版本。TLS协议定义有三个版本号&#xff0c;为0x0301、0x0302、0x0303&#xff0c;分别对应TLS 1.0、1.1、1.2。国密SSL为了避免冲突&am…

Spanner on a modern columnar storage engine 中文翻译

文章目录 0. 摘要1. 存储引擎2. 存储引擎迁移的挑战2.1 可靠性、可用性和数据完整性2.2 性能和成本2.3 复杂性 3. 迁移可靠性的系统原则方法3.1 可靠性原则和自动化架构3.2 迁移方案和按周迁移3.3 客户 部署感知 调度3.4 管理可靠性、可用性和性能 4. 项目管理和驱动指标概括 0…

在 Linux 中开启 Flask 项目持续运行

在 Linux 中开启 Flask 项目持续运行 在部署 Flask 项目时&#xff0c;情况往往并不是那么理想。默认情况下&#xff0c;关闭 SSH 终端后&#xff0c;Flask 服务就停止了。这时&#xff0c;您需要找到一种方法在 Linux 服务器上实现持续运行 Flask 项目&#xff0c;并在服务器…

【AI视野·今日Robot 机器人论文速览 第六十九期】Wed, 3 Jan 2024

AI视野今日CS.Robotics 机器人学论文速览 Wed, 3 Jan 2024 Totally 5 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers NID-SLAM: Neural Implicit Representation-based RGB-D SLAM in dynamic environments Authors Ziheng Xu, Jianwei Niu, Qingf…

Unity 一文掌握使用AddListener方法为组件事件添加监听器的方法

在Unity中&#xff0c;很多组件都带有事件&#xff0c;比如: Button组件&#xff1a;onClick() Toggle组件&#xff1a;On Value Changed(Boolean) Dropdown组件&#xff1a;On Value Changed(Int32) InputField组件&#xff1a;On Value Changed(String)、On End Edit(Stri…

(源码解析)mybatis调用链之XMLMapperBuilder解析Mapper

创建XMLMapperBuilder对象 XMLMapperBuilder mapperParser new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments()); XMLMapperBuilder继承于BaseBuilder public XMLMapperBuilder(InputStream inputStream, Configuration configu…

《GreenPlum系列》GreenPlum详细入门教程01-GreenPlum介绍

文章目录 第一章 GreenPlum介绍1.MPP架构介绍2.GreenPlum介绍3.GreenPlum数据库架构4.GreenPlum数据库优缺点 GreenPlum&#xff1a;https://cn.greenplum.org/ 第一章 GreenPlum介绍 1.MPP架构介绍 MPP是Massively Parallel Processing的缩写&#xff0c;也就是大规模并行处…

客服系统实现类似发送位置功能

地图选点组件 地图选点组件&#xff0c;类似微信中的“发送位置”功能&#xff0c;该组件可以让用户快速、准确地选择并确认自己的当前位置&#xff0c;并将相关位置信息回传给开发者。 调用示例 调用方式一 通过iframe内嵌调用&#xff0c;地图选点组件的页面会根据开发者设…

听GPT 讲Rust源代码--library/core/benches

File: rust/library/core/benches/slice.rs 文件路径&#xff1a;rust/library/core/benches/slice.rs 这个文件是Rust标准库中的一个示例&#xff08;benchmark&#xff09;文件&#xff0c;用来测试切片&#xff08;slice&#xff09;在不同情况下的性能。 Rust的切片是对数组…

[MySQL] 数据库的主从复制和读写分离

一、mysql主从复制和读写分离的相关知识 1.1 什么是读写分离? 读写分离&#xff0c;基本的原理是让主数据库处理事务性增、改、删操作( INSERT、UPDATE、DELETE) &#xff0c;而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。…

1.4 Unity协程

一、先说接口 接口是不能实例化的&#xff0c;想实例化接口&#xff0c;只能实例化继承了接口的类。 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks;namespace InterfaceTest {interface IMyInterfa…

Ranger UserSync

作用 同步User到RangerDb 架构 解析 启动一个while(True) 进程定时同步&#xff0c;程序入口 source sink 掉接口获取Ranger User 并且Cache 计算delta 同步

静态网页设计——清雅古筝网(HTML+CSS+JavaScript)

前言 声明&#xff1a;该文章只是做技术分享&#xff0c;若侵权请联系我删除。&#xff01;&#xff01; 感谢大佬的视频&#xff1a; https://www.bilibili.com/video/BV1T64y1K7Zn/?vd_source5f425e0074a7f92921f53ab87712357b 使用技术&#xff1a;HTMLCSSJS&#xff08;…
最新文章