Mybatis中SqlSession执行Mapper的过程

上篇文章介绍了Mybatis中的SqlSession组件的创建,创建SqlSession之后需要利用SqlSession执行对应的Mapper。Mapper分为两部分,一部分是JAVA的Mapper接口,另一部分是Mapper.xml或者注解的Sql语句。本篇文章分析SqlSession是如何执行Mapper的。

Mapper接口动态代理对象的生成

获取SqlSession之后我们需要通过SqlSession的getMapper()方法,传入当前Mapper接口的Class对象。返回值是一个绑定了当前SqlSession的Mapper对象,之后便可以调用该Mapper对象定义好的接口方法。如下所示:

这种通过调用Mapper接口定义的方法也是写代码时使用Myabtis的方式。那么大家有没有思考过一个问题,平常能直接调用接口定义的方法吗?

也就是说肯定有一个对应的实现类,创建该实现类的实例之后才能通过该类的实例调用该方法。

我们可以看看session.getMapper()方法:

如上图所示,SqlSession.getMapper()通过configuration的getMapper()方法获取对应的实例。Configuration中getMapper()的实现为:

如上图所示,通过mapperRegistry的getMapper()方法获取对应的实例。MapperRegistry最终从kownMappers中获取对应的MapperProxyFactory,最终通过MapperProxyFactory的newInstance()方法创建对应的MapperProxy实例,其代码如下:

上述代码中需要搞清楚MapperProxyFactory从何而来。

configuration中的getMapper()方法里从mapperRegistry中获取Mapper的代理对象,mapperRegistry的定义为

其声明了一个addMapper()方法,通过addMapper()方法将对应的MapperProxyFactory放入knowMappers中

而addMapper()方法在初始化configuration时解析mappers标签相关属性后被调用。

代理对象的invoke方法

生成了动态代理对象之后,调用动态代理对象的方法时会执行该动态代理对象的invoke方法,MapperProxy的invoke()方法如下所示,最终调用PlainMethodInvoker的invoke()方法。

PlainMethodInvoker的invoke()方法如下所示:

最终调用MapperMethod的execute()方法。

execute()方法最终通过SqlSession完成与Myabtis核心组件的交互。

SqlSession执行Mapper

Mybatis调用MapperMethod的execute()方法,在该方法里用SqlSession提供的api执行数据库的操作。 接下来以insert()方法举例,看看SqlSession如何执行Mapper。

构造MapperMethod需要两个属性,一是commond,二是method。这两个属性在MapperMehtod的构造函数中创建,如下所示:

SqlCommand对象用于获取SQL语句的类型、Mapper的Id等信息;MethodSignature对象用于获取方法的签名信息,例如Mapper方法的参数名、参数注解等信息。

构造完成之后调用SqlSession的insert操作,最终转变为调用SqlSession的update操作,如下所示:

如上图所示,在update()方法中先获取MappedStatement对象,之后调用SqlSession持有的executor的update()方法。

前面文章中介绍过MappedStatement对象用来描述SQL相关信息。SQL信息分为两种,一是mapper.xml配置的SQL信息,另一类是通过注解配置的SQL信息,其在configuration初始化时被加载。

之后调用sqlSession持有的executor的update()方法。以SimpleExecutor为例,调用update()之后会调用到SimpleExecutor的doUpdate()方法。

如上所示,先获取到configuration对象,之后获取到对应不同类型的StatementHandler。之后通过调用prepareStatement()获取Connection对象的Statement对象。

随后调用handler的update()方法完成此次交互。以SimpleStatementHandler为例,其update的实现如下所示:

调用JDBC的statement对象的execute方法完成与JDBC的交互,至此MyBatis执行Mapper完毕。

总结

Myabatis先获取Mapper接口对应的动态代理对象,执行其invoke()方法,最终调用MapperMethod的execute()方法,execute方法通过SqlSession完成与Mybatis核心组件的交互。 SqlSession持有executor,通过调用executor封装的方法完成与JDBC的交互。

相关推荐
柴薪之王、睥睨众生2 分钟前
(自用)Java学习-5.8(总结,springboot)
java·开发语言·spring boot·学习·mybatis
唐僧洗头爱飘柔952711 小时前
【SSM-SSM整合】将Spring、SpringMVC、Mybatis三者进行整合;本文阐述了几个核心原理知识点,附带对应的源码以及描述解析
java·spring·mybatis·springmvc·动态代理·ioc容器·视图控制器
淘源码d12 小时前
什么是ERP?ERP有哪些功能?小微企业ERP系统源码,SpringBoot+Vue+ElementUI+UniAPP
java·源码·erp·erp源码·企业资源计划·企业erp·工厂erp
意倾城20 小时前
浅说MyBatis-Plus 的 saveBatch 方法
java·mybatis
Brilliant Nemo1 天前
五、框架实战:SSM整合原理和实战
maven·mybatis
小赵面校招1 天前
Spring Boot整合MyBatis全攻略:原理剖析与最佳实践
java·spring boot·mybatis
小赵面校招1 天前
SpringBoot整合MyBatis-Plus:零XML实现高效CRUD
xml·spring boot·mybatis
悟空打码2 天前
MyBatis源码解读5(3.1、缓存简介)
缓存·mybatis
多多*2 天前
Java反射 八股版
java·开发语言·hive·python·sql·log4j·mybatis
Auc242 天前
OJ判题系统第4期之判题机模块架构——设计思路、实现步骤、代码实现(工厂模式、代理模式的实践)
java·spring cloud·log4j·mybatis·代理模式·工厂模式