iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >Mybatis(五)------Mybatis执行Mapper接口的方法流程
  • 772
分享到

Mybatis(五)------Mybatis执行Mapper接口的方法流程

mybatisjavamysql 2023-09-16 06:09:14 772人浏览 薄情痞子
摘要

前面几篇文章我们介绍了JDBC、mybatis的工具类等,下面我们开始对于mybatis的各个机制开始解析。 前面我们知道,mybatis对excutor进行封装成sqlsession提供给开发人员进行数据库的增删改查,我们先从Mybati

前面几篇文章我们介绍了JDBC、mybatis工具类等,下面我们开始对于mybatis的各个机制开始解析。

前面我们知道,mybatis对excutor进行封装成sqlsession提供给开发人员进行数据库的增删改查,我们先从Mybatis最顶层的api入手。

SQLSession的创建过程分为3个阶段:

1)、Configuration实例的创建(配置类)

2)、SQLSessionFactory实例的创建(工厂类)

3)、SQLSession实例的创建

解析xml文件

        mybatis的主配置文件和mapper配置文件常用的都是xml格式,Configuration组件用来描述主配置文件等信息,框架在启动时会解析xml配置文件,然后将其转换为Configuration对象。

jdk API中提供了3中方式去解析xml,分别为DOM、SAX、XPath。其中最易使用的是Xpath方式,Mybatis也是采用XPath方式去解析xml文件。

我们可以看看如何使用XPath方式解析xml文件:

假如我们有xml文件将其映射为实体对象:

使用XPath方式进行解析:

 

 为了简化XPath解析操作,Mybatis通过XPathParser工具类封装了对xml的解析操作,同时使用Xnode类增强对xml节点的操作。使用XNode对象,我们可以很方便的获取节点的属性、子节点等信息。

我们可以看看XPathParser如何进行解析:

 可以看到XPathParser对xml解析,省去了Dociment对象和XPath对象的创建过程,还封装了执行XPath表达式的方法,简化了xml解析的过程。

Configuration实例创建

Configuration组件主要有下面三个作用:

1)、用于描述mybatis的主配置信息,例如等标签

2)、作为容器注册存储Mybatis的其他组件,例如TypeHandler、MapperStatement等

3)、提供工厂方法,创建ResultSetHandler、StatementHandler、Executor、ParameterHandler等组件实例

SqlSession实例化前,会先解析mybatis的主配置文件+所有Mapper文件,其中部分配置文件由Configuration对象存储。mybatis通过XMLConfigBuilder类完成对Configuration对象的构建。例如下面的代码:

 进入parse方法:

 进入parseConfiguration方法

 我们·先看看主配置xml文件大概是这样的:

mybatis中传进来了XNode root(实际就是标签及包含内容),然后依次处理多个子标签,例如等。我们列出了各个标签的作用如下:

 

 对于每个标签的解析细节,可以自行阅读源码

 3、SqlSession实例创建过程

mybatis创建Sqlsession使用工厂模式创建,在创建之前需要先创建SqlSessionFactory对象,然后调用工厂对象的openSession方法,例如:

进入build方法:

可以看到先创建一个XMLConfigBuilder对象,然后调用 XMLConfigBuilder对象的parse方法对主配置类进行解析,然后返回Configuration对象作为build方法的参数,我们再看看这个重载的build方法:

我们再看看DefaultSqlSessionFactory类对openSession方法的实现:

 进入openSessionFromDataSource方法是如何返回一个SqlSession实例的:

 

(这也就证实了之前说的SqlSession是对Executor的封装的面向开发人员的实例,用来执行增删改查等功能) 

=============================SqlSession 执行Mapper的过程====================

上面讲了如何解析xml配置文件、怎么创SqlSession实例(可以看成sql的执行器),下面我们开始看看SqlSession如何去执行我们定义的Mapper.

一、获取Mapper接口的代理对象

在我们日常开发中,Mapper一般分为两部分,Mapper接口+XML/注解,我们先看看如何去执行Mappper中定义的方法:

如上面所示,创建SqlSession实例后,需要调用getMappper获取Mappper对象(接口的代理对象),然后再去调用相应方法。

而这个Mapper接口的代理在mybatis中是由MapperProxy代理工具类去实现的,MapperProxy工具类的关键代码如下:

在java中常用的动态代理一般有两种方式,jdk动态代理和cglib动态代理。MapperProxy使用了JDK动态代理,实现了InvocationHandler接口,在invoke方法中为统一的拦截逻辑,然后需要调用java.lang.reflect.Proxy类的newProxyInstance方法创建代理对象。创建代理对象的过程mybatis使用MapperProxyFactory进行封装,具体代码:

注意:拦截的代理逻辑是在MapperProxy中的invoke方法定义的,而创建代理对是使用MapperProxyFactory工厂返回代理对象MapperProxy的,MapperProxyFactory中的newInstance方法会去实例化一个MapperProxy进行返回。

可以看到,最后是由MapperProxyFactory进行创建了代理对象,这里需要注意的是newInstance方法并不是静态方法,也就是说我们要调用这个方法需要先实例化MapperProxyFactory对象,那么这个工厂对象是什么时候被创建的?

我们之前在说的Configuration配置对象时,里面就有个mapperReGISter属性,具体如下:

 

 而mapperRegister是用来注册Mapper接口和MapperProxyFactory对象之间的关系:

(注意:MapperProxyFactory的类型T指定我Mapper的类型,即一个Mapper对应一个MapperProxyFactory对象)

 

 可以看出用了一个map来存储Mapper接口的Class对象与MapperProxyFactory对象之间的关系,然后在addMapper方法向其中注册关系,然后就能调用getMapper方法根据Mapper接口的来获取对应的代理对象(通过对应的MapperProxyFactory调用newInstance方法创建)。

 (mybatis启动时就会解析所以mapper接口,然后调用MapperRegistry对象的addMapper方法将Mapper接口信息和对应的MapperProxyFactory对象注册到MapperRegister对象中,待需要获取mappper的代理对象时调用getMapper执行对应的MapperProxyFactory对象的newInstacne方法返回代理对象)

二、MapperStatement的注册过程(Mapper中标签或注解的配置类)

前面已经说过,mybatis通过MappedStatement类描述Mapper的sql配置信息。而在将Configuration对象时,说过Configuration类有一个mappedStatements属性,该属性用来注册Mybatis中所有的MappedStatement对象,具体如下:

 在讲Configuration时,我们讲过Mybatis主配置文件的解析通过XMLConfigBuilder对象完成的,XmlConfigBuilder类通过parseConfiguration方法中去调用不同的方法解析对应的标签:

 而MappedStatement对象的创建重点需要关注的是对标签的解析过程,我们进入mapperElement方法:

如上代码,首先获取的所有子标签,然后根据不同标签做不同的处理,mappers标签的配置一般如下: (标签表示一个Mapper的配置,例如一个UserMapper接口就对应一个

 获取到子标签信息后,就创建XMLMapperBuilder对象并调用parse方法进行解析,我们进入该方法:(我们这里以这个子标签来看看parse方法怎么解析的,即看怎么解析Mapper.xml文件的)

首先会调用XPathParser对象的evalNode方法获取根节点对应的XNode对象,接着调用configurationElement方法对Mapper配置内容进一步做解析,我们进去看看configurationElement方法:

 如上面代码所示,configurationElement方法对Mappper.xml文件的所有标签进行解析,这里我们重点关注标签的解析,在上面代码中获取到标签对应的XNode对象后,调用buildStatementFromContext方法进一步做解析:

可以看到该方法为每个标签对应的XNode对象创建一个XMLStatementBuilder对象,然后调用其parseStatementNode方法进行解析。我们进入parseStatementNode方法看看:

可以从XMLStatementBuilder类的parseStatementNode方法看出解析标签对应的XNode对象大概分下面几个步骤:

三、调用Mapper方法

上面讲了获取Mapper接口的动态代理对象,创建MapperStatement配置对象,下面开始看看怎么去调用Mapper接口中定义的方法。

 为了执行Mapper接口中定义的方法,我们需要调用SqlSession对象的getMapper方法获取一个动态代理对象,然后通过动态代理对象调用方法即可,具体如下:

 我们前面说过调用代理对象方法时,会执行MapperProxy类的invoke方法:

 此时对Mapper接口的方法,调用cachedMapperMethod方法获取到一个MapperMethod对象:我们先看 cachedMapperMethod方法:

 首先该方法中从缓存中获取MapperMathod对象,如果获取不到则创建一个并放进缓存中,而MapperMethod是对Mapper方法相关信息的封装,通过MapperMethod能够方便的获取sql语句的类型、方法的签名信息等。下面是MapperMethod类的构造方法:

 MapperMethod构造方法中创建了一个SqlCommand对象和一个MethodSignature对象,SqlCommand对象用于获取Sql语句的类型、Mapper的Id等信息。MethodSignature对象用于获取方法的签名信息、参数注解等信息。我们先看下SqlCommand类的构造方法:

可以看出现获取方法的类或接口的class对象,然后调用resolveMappedStatement方法根据Mapper接口的全限定名和方法名获取对应的MappedStatement对象(配置对象),然后通过MappedStatement对象获取Sql语句的类型和mapper的id。下面是ResolveMappedStatement方法的实现:

 可以看到先将接口的全限定名+方法进行拼接,作为Mapper的id从Configuration对象中查找对应的MappedStatement对象,查找不到先从父接口递归调用,还找不到则返回null。

SqlCommand封装了Sql语句的类型和Mapper的id,下面我们看看MethodSignature对象的创建过程,下面是MethodSignature的构造方法:

ParaNameResolver构造方法中完成了Mapper方法参数的解析过程,代码如下:

 

到此我在,整个MapperMethod对象已经创建完成,接下来解释Mapper方法的执行,MapperMethod提供了一个execute方法用来 执行sql命令,我们可以回到MapperProxy的invoke方法看看:

进入改execute方法:

 

 如图所述,先通过SqlCommand获取sql语句的类型,然后根据类调用SqlSession对象对应的方法

例如Insert类型,先获取参数信息,然后通过SqlCommand的getName方法获取Mapper的id(全限定类或接口名+方法名),然后调用SqlSession的api。

四、SqlSession执行Mapper过程

上面我讲了先通过动态代理获取Mappper的代理对象,而代理方法invoke方法(代理方法调用时会调用,代理方法逻辑是通过Mapperproxy类,而代理对象的创建时通过MapperProxyFactory工厂实例化MapperProxy对象返回)中创建一个MapperMethod对象(用来描述Mappe接口中方法信息的对象),然后通过调用该对象的execute方法去执行sql语句。

而execute中执行sql语句是通过sqlsession提供的增删改查的方法。大概流程如下例子:

下面我们以select类型为例子,介绍SqlSession怎么执行Mapper的?我们之前的文章讲过SqlSessioon接口只有一个实现类就是DefaultSqlSession,下面是DefaultSqlSession类对SqlSession接口中定义的SelectList方法的实现:

上面代码中先根据Mapper的Id获取MappedStatement对象,然后作为参数调用Executor实例的query方法完成查询操作,我们来看看Excutor的实现类BaseExecutor对query方法的实现:

 BaseExecutor类的query反方中,先对从MappedStatement对象中获取BoundSql对象,该对象封装了经过解析后的sql语句以及参数映射信息,然后创建CacheKey对象,该对象用于缓存Key值,接着调用重载query放,代码如下:

 先从缓存中获取查询结果,如果没有则调用queryFromDatabase方法从数据库中查询,该方法的关键代码如下:

 调用doQuery方法进行查询,然后将查询结果进行缓存,doQuery是一个模板方法,由BaseExecutor子类实现(SimpleExecutor、ReuseExecutor),我们以SimpleExecutor对doQuer方法的实现举例:

 SimpleExecutor类的doQuery方法中,首先使用Configuration对象的newStatementHandler方法创建了StatementHandler对象(此时返回了一个RoutingStatementHandler类型的),在RoutingStatementHandler中会根据配置Mapper是StatementType属性指定的StatementHandler类型创建对应的StatementHandler实例进行处理(例如statementType属性为simple时则创建SimpleStatementHandler实例)

        StatementHandler对象创建完后,就会调用SimpleExecutor类的prepareStatement方法创建JDBC中的Statement对象(JDBC中的sql执行器),然后对Statement对象设置参数操作,Statement对象初始化后,再去调用其query方法执行操作,我们在来看看prepareStatement放怎么去创建Statement对象的。具体代码如下:

 上面代码中,首先会获取JDBC的Connection对象吗,然后调用StatementHandler对象的prepare方法创建Statement对象,接着调用StatementHandler对象的parametersize方法(该方法会使用Parameterhandler为Statement对象设置参数)

(StatementHandler、parameterHandler都是mybatis对JDBC的Statement、Parameter操作的封装)

mybatis的StatementHandler有几个不同的实现类,分别为SimpleStatementHandler、PrepareStatementHandler、CallableStatementHandler,默认情况下回使用PreparedStatementHandler与数据库交互,接下来我们来看看PreparedStatementhandler中对query方法的实现,代码如下:

 首先调用了PrepareStatement对象的execute方法执行sql语句,然后调用ResultSetHandler的handleResultSet方法处理结果集。

ResultSetHandler只有一个默认的实现,即DefaultResultSetHandler类,下面是其handleResultSet方法的关键代码:

如上图所示,该方法的具体实现步骤如下:

 小结:

aaa

来源地址:https://blog.csdn.net/qq_35599414/article/details/129938161

您可能感兴趣的文档:

--结束END--

本文标题: Mybatis(五)------Mybatis执行Mapper接口的方法流程

本文链接: https://www.lsjlt.com/news/409507.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Mybatis(五)------Mybatis执行Mapper接口的方法流程
    前面几篇文章我们介绍了JDBC、Mybatis的工具类等,下面我们开始对于mybatis的各个机制开始解析。 前面我们知道,mybatis对excutor进行封装成sqlsession提供给开发人员进行数据库的增删改查,我们先从Mybati...
    99+
    2023-09-16
    mybatis java mysql
  • Mybatis SqlSession执行流程介绍
    这篇文章主要讲解了“Mybatis SqlSession执行流程介绍”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Mybatis SqlSession执行流程介绍”吧!目录Mybatis执行...
    99+
    2023-06-20
  • 浅谈Mybatis SqlSession执行流程
    目录Mybatis执行SQL流程 SqlSessionExecutorMybatis之Executor Mybatis之StatementHandler 进入ResultSetHan...
    99+
    2024-04-02
  • 解决mybatis 执行mapper的方法时报空指针问题
    mybatis报空指针 今天在test类掉用service层往数据库存数据的时候,控制台报空指针异常。找了很久找不到原因。 解决 配置文件,注解,依赖都是对的。 最后发现是因为在te...
    99+
    2024-04-02
  • MyBatis详细执行流程的介绍
    本篇内容介绍了“MyBatis详细执行流程的介绍”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!Mybatis简介MyBatis 是一款优秀的...
    99+
    2023-06-14
  • 【Mybatis源码解析】mapper实例化及执行流程源码分析
    文章目录 简介 环境搭建 源码解析 附 基础环境:JDK17、SpringBoot3.0、mysql5.7 储备知识:《【Spring6源码・AOP】AOP源码解析》、《JDBC详细...
    99+
    2023-08-20
    mybatis java spring boot
  • Mybatis中的PageHelper的执行流程分析
    PageHelper Mybatis的执行流程 mybatis中首先要在配置文件中配置一些东西然后根据这些配置去创建一个会话工厂再根据会话工厂创建会话,会话发出操作数据库的sql语...
    99+
    2024-04-02
  • SpringBoot+Mybatis使用Mapper接口注册的几种方式
    目录I.环境准备1.数据库准备2.项目环境II.实例演示1.实体类,Mapper类2.注册方式2.1@MapperScan注册方式2.2@Mapper注册方式2.3MapperSca...
    99+
    2024-04-02
  • Mybatis执行SQL命令的流程分析
    目录MapperProxy的功能:MapperMethod的功能:Mybatis中的Sql命令,在枚举类SqlCommandType中定义的。 public enum SqlComm...
    99+
    2023-05-16
    Mybatis执行SQL命令 Mybatis执行SQL
  • mybatis框架的执行流程是什么
    MyBatis框架的执行流程大致如下: 加载MyBatis配置文件:MyBatis会读取并解析mybatis-config.xm...
    99+
    2024-04-02
  • MyBatis详细执行流程的全纪录
    Mybatis简介 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。...
    99+
    2024-04-02
  • mybatis中mapper接口的工作原理是什么
    MyBatis中的Mapper接口是用于定义SQL映射的接口。它的工作原理可以分为以下几个步骤:1. 定义Mapper接口:创建一个...
    99+
    2023-08-08
    mybatis mapper
  • mybatis mapper配置的方法是什么
    MyBatis的Mapper配置方法包括以下两种方式:1. XML配置文件:在XML配置文件中定义Mapper接口与SQL语句的映射...
    99+
    2023-09-29
    mybatis
  • 关于Mybatis的mapper接口函数重载问题
    目录Mybatis的接口函数能不能进行重载?语法层面Mybatis框架方面测试MyBatis实现方法重载的小技巧QuestionMapper.javaQuestionMapper.x...
    99+
    2024-04-02
  • Mybatis通过Mapper代理连接数据库的方法
    1.在数据库中创建表和相应字段,如下图我创建了三个字段分别为fromname,message,toname,类型为varchar 2.创建对应的pojo实体类,注意类型要和数据库创...
    99+
    2024-04-02
  • mybatis中的映射文件怎么利用mapper接口进行加载
    mybatis中的映射文件怎么利用mapper接口进行加载?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。通过 mapper 接口加载映射文件,这对于后面 ssm三大框架 的整合...
    99+
    2023-05-31
    mybatis mapper pp
  • MyBatis注解CRUD与执行流程是什么
    这篇文章主要介绍了MyBatis注解CRUD与执行流程是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇MyBatis注解CRUD与执行流程是什么文章都会有所收获,下面我们一起来看看吧。结果映射ResultM...
    99+
    2023-07-05
  • 使用Spring扫描Mybatis的mapper接口的三种配置
    Spring扫描Mybatis的mapper接口的配置 1.前言 mybatis支持与spring结合使用,使得mybatis中的mapper接口可以作为spring容器中的bean...
    99+
    2024-04-02
  • Mybatis中mapper的map方法怎么使用
    在MyBatis中,Mapper接口中的map方法是用来执行SQL语句并将结果映射到Java对象的。首先,在Mapper接口中定义一...
    99+
    2023-10-12
    Mybatis
  • mybatis中mapper映射的方法是什么
    在MyBatis中,Mapper映射的方法是通过SQL语句来操作数据库。Mapper映射文件中定义了一系列的SQL语句,这些SQL语...
    99+
    2023-09-16
    mybatis
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作