浅入浅出Mybatis:(四)SQL执行过程

前言

在前几篇中,我们对MyBatis的源码进行了简单分析,大体了解了MyBatis的工作流程,以及MyBatis是如何去加载Mapper配置文件的,那么,我们又有了新的疑问,MyBatis是如何执行一条SQL的呢?本篇,我们就来解开这个问题。

MyBatis SQL执行流程

我们在使用MyBatis进行开发时,只需要编写一个Mapper interface,关联好配置XML文件,使用Spring的AutoWired注解进行一下注入,就可以使用了,那么这里有个问题,我们仅仅编写了一个interface,并没有编写对应的实现类,MyBatis是如何执行到配置文件中的SQL语句呢?

MyBatis的源代码,我们的核心原则一定是观其大略,不要深抠细节,MyBatis作为一个极为成熟的框架,有大量的细枝末节的逻辑处理,如果太纠结于这些细节信息,会看的头昏脑胀,陷入泥潭之中,因此,我们主要是要理解MyBatis的核心执行逻辑,了解其设计的思想精华所在,抓住主干,核心脉络,有的放矢。

MapperProxy代理模式

答案是使用代理类的方式进行实现,说到代理,你肯定并不陌生,在Spring中,大量的采用了代理的模式进行实现,MyBatis也同样采用了代理的方式,我们来通过Debug来验证一下,我们的说法是否是正确的:

MyBatis interface

我们使用AutoWired注入一个Mapper interface,如上图所示,我们可以看到,其交给Spring管理的实现类,是一个MapperProxy类,进入MapperProxy看看其实现。

Mapper Proxy

MapperProxy实现了InvocationHandler接口,实现了invoke()方法,我们对invoke()方法进行简要的分析:

1、判断代理对象是否是方法所声明的Class,使用Spring的情况下,代理对象为MapperProxy,因此条件不成立;

2、判断执行的方法是否是默认方法,默认方法(default method)是在Java 8以后加入的,是指在接口中定义的公共非抽象的方法,关于默认方法的解释,可以参考:https://www.geeksforgeeks.org/default-methods-java/

3、检查待执行的mapperMethod是否已经缓存,如果已经缓存,那么直接取出缓存的对象,反之,进行缓存;

4、真正的SQL执行逻辑。

前三步都是进行的各种判断逻辑,第四步才是我们真正关心的核心逻辑,下面,我们来看一下SQL的执行逻辑。

SQL执行解析

MapperMethod

SQL的执行逻辑在MapperMethod,我们进入MapperMethodexecute()方法:
MapperMethod execute 1MapperMethod execute 2

MapperMethodexecute()方法中,可以看到,会根据不同的方法类型,执行不同的逻辑操作,SQL的执行类型分为增删改查以及刷新,而方法的类型来源,则是根据MappedStatement的信息进行得到的,MappedStatement的初始化,则是在Spring容器的启动过程中完成的,也就是我们上篇中所讲到的Mapper关联SQL配置加载过程,如果您没有读过上一篇,可以回顾:浅入浅出Mybatis:(三)Mapper关联SQL配置加载过程

DefaultSqlSession

我们回到主干,继续分析,这里,我们以INSERT操作举例说明,SQL的执行操作,最终是通过SqlSession来进行执行的,而SqlSession接口的默认实现类,为DefaultSqlSession,我们继续跟进:

Default SqlSession

INSERT方法最终调用的是update方法的实现,在方法中,获取了MappedStatement对象,其包含了SQL语句的内容,继续跟进:

调用BaseExecutorupdate方法,

BaseExecutor

SimpleExecutor

最终调用默认的SimpleExecutordoUpdate()

SimpleExecutor

doUpdate()方法中,是真正的SQL执行的逻辑,我们来看一下:

1、获取MappedStatement对象的Configuration对象,获取核心配置信息;

2、组装StatementHandler,加载plugin插件,生成代理方法;

3、执行SQL,返回结果集。

针对步骤2,我们来简单分析一下:

newStatementHandler

InterceptorChain

这里首先创建了一个默认的RoutingStatementHandler对象,接下来,调用plugin责任链,MyBaits使用责任链的方式来加载plugin插件类,通过生成代理的方式,来执行插件方法,这里值得注意的是:

  1. 形参Object target,这个是Executor、ParameterHandler、ResultSetHandler、StatementHandler接口的实现类,换句话说,plugin方法是要为Executor、ParameterHandler、ResultSetHandler、StatementHandler的实现类生成代理,从而在调用这几个类的方法的时候,其实调用的是InvocationHandlerinvoke方法;
  2. 这里的target是通过for循环不断赋值的,也就是说如果有多个拦截器,那么如果我用P表示代理,生成第一次代理为P(target),生成第二次代理为P(P(target)),生成第三次代理为P(P(P(target))),不断嵌套下去,这就得到一个重要的结论:<plugins>...</plugins>中后定义的<plugin>实际其拦截器方法先被执行,因为根据这段代码来看,后定义的<plugin>代理实际后生成,包装了先生成的代理,自然其代理方法也先执行。

关于插件,这里我们先不过多的介绍,下一篇中,我们会着重介绍plugin的实现。

PreparedStatement

我们继续向下看,StatementHandler生成后,初始化Statement对象,默认情况下,是使用PreparedStatement执行SQL:

prepareStatement初始化

PreparedStatementHandler update

看到这里,是不是熟悉的味道,还是原来的配方,还是原来的味道,最原始的JDBC的执行方式,执行成功后,拿到影响的结果行数,返回。

上面我们对INSERT的执行进行了分析,事实上,QUERY的查询也是一样的逻辑,这里,就不再演示一遍,留给您自己挖掘。

MyBatis $ 与 # 的区别

我们在编写MyBatisSQL语句的时候,经常用到的是#{}的字符去替代其中的查询入参,偶尔也会在网上看到${}这样的字符使用。
对于这两种写法,比较通用的解释是,${}这种写法容易引起SQL注入,那么,这个说法的原因是什么呢?MyBatis是如何实现的呢?下一篇中,我们会解开这个答案。

结语

本篇,我们对MyBatis的SQL执行过程进行了简要分析,对于SQL的执行全过程,我并没有特别详细的展开,避免您陷入细节的泥潭中来,事实上SQL的执行过程中,对于SQL语句的解析还是比较复杂的,其中做了大量的细节逻辑处理,如果您对这方面感兴趣,可以自行深入研究源码。

通过对MyBatis的源码分析,我们了解到其使用了大量的代理模式,这样做的好处是非常的灵活,当然也引入了一定的复杂度,JDK的代理模型也是我们可以好好学习的。

在下一篇中,我们将对MyBatis的SQL解析中的#{}${}的区别进行探究,敬请期待。

更多精彩文章, 请关注我的个人公众号:老宣说
让我们一起共同学习成长!
感谢您的支持!
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值