SpringBoot中,Mybatis的执行流程源码解析

起飞(feí)


1. 准备阶段

我们将SpringBoot项目启动起来的时候,它会为我们加载一些组件以实现MyBatis的执行

  • SqlSessionFactoryBuilder:创建SqlSessionFactory,使用建造者模式
  • SqlSessionFactory:SqlSession的工厂,用于创建SqlSession
  • SqlSession:Through this interface you can execute commands, get mappers and manage transactions,官方注释如上,通过它可以执行命令,接口中有selectOne,selectList等方法;获取mapper和管理事务
  • MapperRegistry:主要调用它的getMapper方法,获取需要的mapper,其中有一个Map<Class<?>, MapperProxyFactory<?>> knownMappers字段,通过这个map获取我们需要的MapperProxyFactory,从而创建MapperProxy对象,
  • MapperProxy:其中封装了三个字段,sqlSession、mapperInterface和methodCache,mapperInterface是我们在dao层写的接口

SqlSessionFactoryBuilder:作用就是创建一个构建器,一旦创建了SqlSessionFactory,它的任务就算完成了,可以回收。
SqlSessionFactory:作用是创建SqlSession,而SqlSession相当于JDBC的一个Connection对象,每次应用程序需要访问数据库,我们就要通过SqlSessionFactory创建一个SqlSession,所以SqlSessionFactory在整Mybatis整个生命周期中(每个数据库对应一个SqlSessionFactory,是单例产生的)。
Mapper:是一个接口,并没有实现类,它的作用是发送SQL,返回我们需要的结果,或者发送SQL修改数据库表,所以它存活于一个SqlSession内,是一个方法级别的东西。当SqlSession销毁的时候,Mapper也会销毁。


在这里插入图片描述打断点!进来!

我们可以在MybatisAutoConfiguration中看到,SpringBoot会为我们加载一个SqlSessionFactory的Bean,其中的applyConfiguration方法会为Factory加载配置
在这里插入图片描述在方法的最后我们可以看到getObject方法,进去看看
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
这里可以看到在SqlSessionFactoryBean中看到它会读取我们的xml配置,然后是一堆读取配置信息的废话,最后我们可以发现一个build方法,接着向下看

在这里插入图片描述在这里插入图片描述这里我们可以很清楚的看到,创建的是一个DefaultSqlSessionFactory
在这里插入图片描述


之后会使用SqlSessionFactory,创建一个SqlSessionTemplate

在这里插入图片描述它调用的是如下构造方法
在这里插入图片描述有了SqlSession会调用他的getMapper方法,在这里我们可以看见需要在Configurantion中获取mapper,而且type就是我们在dao层创建的接口的Class对象
在这里插入图片描述在这里插入图片描述
我们在这里需要特别注意,MapperRegistry出现了!调用getMapper,获取mapper代理对象mapperProxy

在这里插入图片描述其中knownMappers存储的都是我们的mapper接口和对应的mapperProxyFactory
在这里插入图片描述
我们具体看一下MapperProxy的构造方法
在这里插入图片描述我们熟悉其中的字段,sqlSession是我们之前创建的SqlSessionTemplate,MapperInterface是我们创建的dao接口

到了这里,准备阶段就算完成了,画个图瞅瞅
在这里插入图片描述


2. 执行一个Dao中的方法

  • MapperMethod: 其中封装了如下两个字段,其中command包括了方法名和方法类型(Select、Insert、Delete、Update),而MethodSignature包含返回值类型等信息
  private final SqlCommand command;
  private final MethodSignature method;
  • MappedStatement: 包含很多重要字段信息,如resource(加载的xml资源),configuration(配置),resultMap(在mapper.xml文件中resultMap的对应关系),还有我们要使用的BoundSql,下文有图示
    MappedStatement 详解
  • BoundSql:官方注释和其中字段如下

*An actual SQL String got from an {@link SqlSource} after having processed any dynamic content.
*The SQL may have SQL placeholders “?” and an list (ordered) of an parameter mappings
*with the additional information for each parameter (at least the property name of the input object to read the value from).
*Can also have additional parameters that are created by the dynamic language (for loops, bind…).
我们从中可以获取要执行的Sql语句,Sql语句中包含有?占位符和对应的参数映射,它还可以有通过动态语言创建的附加的参数

  private final String sql; //sql语句
  private final List<ParameterMapping> parameterMappings; //参数映射关系
  private final Object parameterObject;
  private final Map<String, Object> additionalParameters;
  private final MetaObject metaParameters;
  • ResultSetWrapper: 其中存着对应的列名,列对应的jdbc类型和对应的Java类型

我们在这个方法里,进去!
在这里插入图片描述这里调用MapperProxy的Invoke方法
在这里插入图片描述之后,会执行MapperMethod的invoke方法
在这里插入图片描述
之后根据sql语句类型继续向下执行,我们这里是SELECT
在这里插入图片描述在这里插入图片描述
接着向下跟
在这里插入图片描述下边是DefaultSqlSession调用SelectOne方法
在这里插入图片描述
下面是第一次执行query方法,正戏开始!
在这里插入图片描述
MappedStatement其他属性如下
在这里插入图片描述
在这里插入图片描述在这里插入图片描述在这里插入图片描述在这里插入图片描述下面这个doQuery方法是SimpleExector调用
在这里插入图片描述


这里我们重点看一下prepareStatement(handler, ms.getStatementLog())方法,在这里它将我们传递的参数set进去了

跟进去!
在这里插入图片描述在这里插入图片描述在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

在这里插入图片描述
根据我们传入的值是Integer,匹配到这个setNonNullParameter的重载方法,调用setInt将我们的参数set进去


在这里插入图片描述
在这里插入图片描述

之后的调用链还很长,就不都截出来了,其中我们注意一下这个rsw变量,其中存的东西有点儿意思,它有列名,列的类型和对应的Java类型
在这里插入图片描述一直查询到后面,其中有一个applyPropertyMappings方法 比较重要,这里它会进行一个循环,会对实体类进行赋值(其中ResultMap,指定的属性和列对应关系,在我们启动项目的时候,就在加载xml文件的时候,被创建好了)
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述其中metaObject中存我们最终获取到的实体类的值
在这里插入图片描述
metaObject具体属性如下

在这里插入图片描述
之后返回到getRowValue方法中,rowValue便是数据库中的行值
在这里插入图片描述
在这里插入图片描述之后就是关闭资源,不断的向前返回result结果

还是画个图总结一下吧,不难

在这里插入图片描述


搞定!!!

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

方圆想当图灵

嘿嘿,小赏就行,不赏俺也不争你

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值