热门框架系列 (二) -- MyBatis执行全流程;

Executor_Type

==========================================================================

Mybatis 一共有两大类Executor 执行器; 第一类就是cache 内存执行器 还有一类就是普通执行器 Executor

在这里插入图片描述

从上图我们可以得知 普通Executor 分为三种 一种是SimpleExecutor 一种是ResuseExecutor 还有一种是BatchExecutor

  1. SimpleExecutor:每执行一次update或select,就开启一个 Statement对象,用完立刻关闭Statement对象

  2. ReuseExecutor:执行update或select,以sql作为key查找 Statement对象,存在就使用,不存在就创建,用完后,不关闭Statement 对象,而是放置于Map<String, Statement>内,供下一次使用。简言之, 就是重复使用Statement对象。

  3. BatchExecutor:执行update(没有select,JDBC批处理不支持 select),将所有sql都添加到批处理中(addBatch()),等待统一执行 (executeBatch()),它缓存了多个Statement对象,每个Statement对象 都是addBatch()完毕后,等待逐一执行executeBatch()批处理。与JDBC批 处理相同。

另外一个大类就是cacheExecutor 是缓存执行器:

CacheExecutor其实是封装了普通的Executor,和普通的区别是在查询前先 会查询缓存中是否存在结果,如果存在就使用缓存中的结果,如果不存在还 是使用普通的Executor进行查询,再将查询出来的结果存入缓存。

我们可以通过openSession来确定自己 即将要使用的执行器; 这个在业务当中有很大作用; 现在我们代码使用的就是普通类型的执行器; 这边就不再累赘每个执行器的执行结果;


在这里插入图片描述

我们可以从返回对象得知 我们的Mapper对象 是代理对象; 既然有代理对象 那么 就一个有代理工厂 来生成这个代理对象; 我们由此引出2个对象MapperProxy

MapperProxyFactory;

在这里插入图片描述

在这里插入图片描述

这样就创建出来了代理Mapper; 我们继续往下走;

在这里插入图片描述

我们知道代理对象执行方法; 执行到MapperProxy 的 invoke 方法 源码不难; 我们解读一次;

public class MapperProxy implements InvocationHandler, Serializable {

private static final long serialVersionUID = -6424540398559729838L;

private final SqlSession sqlSession;

private final Class mapperInterface;

private final Map<Method, MapperMethod> methodCache;

构造方法

public MapperProxy(SqlSession sqlSession, Class mapperInterface, Map<Method, MapperMethod> methodCache) {

this.sqlSession = sqlSession;

this.mapperInterface = mapperInterface;

this.methodCache = methodCache;

}

执行主要方法;

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

try {

判断是否是一个对象; 如果是一个对象 就直接执行他的方法;

这个方法实际上就是Mapper的三种方式是有关系的;

if (Object.class.equals(method.getDeclaringClass())) {

return method.invoke(this, args);

} else if (isDefaultMethod(method)) {

return invokeDefaultMethod(proxy, method, args);

}

} catch (Throwable t) {

throw ExceptionUtil.unwrapThrowable(t);

}

最后走到这个地方; 引出一个对象 MapoperMethod

final MapperMethod mapperMethod = cachedMapperMethod(method);

return mapperMethod.execute(sqlSession, args);

}

private MapperMethod cachedMapperMethod(Method method) {

MapperMethod mapperMethod = methodCache.get(method);

if (mapperMethod == null) {

mapperMethod = new MapperMethod(mapperInterface, method, sqlSession.getConfiguration());

methodCache.put(method, mapperMethod);

}

return mapperMethod;

}

在这里插入图片描述

该对象是sql执行 的一个对象; 该对象带着sql的属性;带着返回值 我们可以从途中可以看出; 最后由mapperMethod.execute 执行

在这里插入图片描述

我们可以看出execute 会根据Type去判断 如果是select 就直接进select

这时候 DefaultSqlSession 就会去执行sql; 我们持续往下深挖;最后我们会到BaseExecutor.在这里插入图片描述

这里就会由模板模式去决定调取哪个 Executor

到此 我们Mybatis的全部流程 就讲解完了。

总结

==============================================================

Mybatis 是一个非常适合新手上手源码的框架 非常的简单;

  • SqlSessionFactoryBuilder解析配置文件,包括属性配置、别名配置、 拦截器配置、环境(数据源和事务管理器)、Mapper配置等;解析完这些 配置后会生成一个Configration对象,这个对象中包含了MyBatis需要的所 有配置,然后会用这个Configration对象创建一个SqlSessionFactory对 象,这个对象中包含了Configration对象;

  • 拿到SqlSessionFactory对象后,会调用SqlSessionFactory的 openSesison方法,这个方法会创建一个Sql执行器(Executor组件中包含 了Transaction对象),这个Sql执行器会代理你配置的拦截器方法。

  • 获得上面的Sql执行器后,会创建一个SqlSession(默认使用 DefaultSqlSession),这个SqlSession中也包含了Configration对象和上面 创建的Executor对象,所以通过SqlSession也能拿到全局配置;

  • 获得SqlSession对象后就能执行各种CRUD方法了


以上是获得SqlSession的流程,下面总结下本博客中介绍的Sql的执行流程:

  • 调用SqlSession的getMapper方法,获得Mapper接口的动态代理对 象MapperProxy,调用Mapper接口的所有方法都会调用到MapperProxy 的invoke方法(动态代理机制);

  • MapperProxy的invoke方法中唯一做的就是创建一个 MapperMethod对象,然后调用这个对象的execute方法,sqlSession会 作为execute方法的入参;

  • 往下,层层调下来会进入Executor组件(如果配置插件会对Executor 进行动态代理)的query方法,这个方法中会创建一个StatementHandler 对象,这个对象中同时会封装ParameterHandler和ResultSetHandler对 象。调用StatementHandler预编译参数以及设置参数值,使用 ParameterHandler来给sql设置参数


Executor组件有两个直接实现类,分别是BaseExecutor和 CachingExecutor。CachingExecutor静态代理了BaseExecutor。Executor 组件封装了Transction组件,Transction组件中又分装了Datasource组件。

  • 调用StatementHandler的增删改查方法获得结果,ResultSetHandler 对结果进行封装转换,请求结束。

Executor、StatementHandler 、ParameterHandler、 ResultSetHandler,Mybatis的插件会对上面的四个组件进行动态代理。


  • MapperRegistry:本质上是一个Map,其中的key是Mapper接口的 全限定名,value的MapperProxyFactory;

  • MapperProxyFactory:这个类是MapperRegistry中存的value值, 在通过sqlSession获取Mapper时,其实先获取到的是这个工厂,然后通过 这个工厂创建Mapper的动态代理类;

  • MapperProxy:实现了InvocationHandler接口,Mapper的动态代理 接口方法的调用都会到达这个类的invoke方法;

  • MapperMethod:判断你当前执行的方式是增删改查哪一种,并通过 SqlSession执行相应的操作;

总结

以上是字节二面的一些问题,面完之后其实挺后悔的,没有提前把各个知识点都复习到位。现在重新好好复习手上的面试大全资料(含JAVA、MySQL、算法、Redis、JVM、架构、中间件、RabbitMQ、设计模式、Spring等),现在起闭关修炼半个月,争取早日上岸!!!

下面给大家分享下我的面试大全资料

  • 第一份是我的后端JAVA面试大全

image.png

后端JAVA面试大全

  • 第二份是MySQL+Redis学习笔记+算法+JVM+JAVA核心知识整理

字节二面拜倒在“数据库”脚下,闭关修炼半个月,我还有机会吗?

MySQL+Redis学习笔记算法+JVM+JAVA核心知识整理

  • 第三份是Spring全家桶资料

字节二面拜倒在“数据库”脚下,闭关修炼半个月,我还有机会吗?

MySQL+Redis学习笔记算法+JVM+JAVA核心知识整理
21194100175)]

后端JAVA面试大全

  • 第二份是MySQL+Redis学习笔记+算法+JVM+JAVA核心知识整理

[外链图片转存中…(img-9IyFGxV0-1721194100176)]

MySQL+Redis学习笔记算法+JVM+JAVA核心知识整理

  • 第三份是Spring全家桶资料

[外链图片转存中…(img-3FLSoGYR-1721194100176)]

MySQL+Redis学习笔记算法+JVM+JAVA核心知识整理

  • 11
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值