1. 架构分层

    我们将MyBatis架构分为三层,分别为接口层、数据处理层和框架支撑层

    • 接口层:提供外部接口调用的API,使用端通过这些API来操作数据库,接口层收到请求后会调用数据处理层完成具体的数据处理

      使用端可以通过两种方式调用接口层:MyBatis提供的API、Mapper动态代理

    • 数据处理层:负责具体的SQL查找、解析、执行与执行结果映射处理,主要负责根据具体的请求完成数据库操作

    • 框架支撑层:负责基础的功能支撑,主要功能有连接管理、事务管理、配置加载和缓存管理

  2. 主要组件及关系

    组件 功能描述
    Configuration 接收使用端配置的MyBatis XML核心配置文件
    MappedStatement 接收使用端配置的XxMapper.xml文件
    SqlSession 负责与数据库交互的会话,主要封装了代理对象、增删改查、获取数据库连接
    Executor 执行器,MyBatis的核心调度器,主要负责动态语句的生成、事务管理及缓存操作
    StatementHandler 封装了诸多类,调度参数映射、SQL执行与结果集映射,主要负责 操作JDBC Statement对象执行SQL,
    ParameterHandler 负责将使用端传递的参数转换成JDBC Statement所需要的参数
    ResultSetHandler 负责将JDBC返回的ResultSet结果集对象转换成List类型的集合
    TypeHandler 主要负责JDBC对象与Java对象之间进行相互转换
    BoundSql 处理SQL中的#{} ${},进行替换处理,转换为数据库可执行的SQL
    RowBounds MyBatis提供的逻辑分页类,从结果集中进行过滤分页数据
  3. 执行流程

    1、读取Mybatis主配置文件信息

    2、获取SqlSessionFactory

    ​ a、使用XMLMappperBuilder解析Mybatis配置文件,封装成Environment对象,再把Environment对象设置给Configuration对象;

    ​ b.、调用ConfigurationElement函数,最终执行addMappedStatement方法,将mapper配置文件中的每一条SQL语句封装成mappedStatement对象,作为value保存在HashMap集合中;

    ​ c.、进入addLoaderResource方法,使用HashSet集合存放mybatis的mapper.xml 映射文件路径地址;

    ​ d.、进入bindMapperForNamespace()方法,通过namespace使用Java反射机制找到mapper接口,再调用addMapper()方法,判断是否是接口类型,是否注册过(注册过则抛出异常)其中mapperRegistry通过HashMap保存mapper接口,【key:接口;value:MapperProxyFactory】

    3、获取SqlSession对象

    ​ a、进入openSession()方法,执行newExecutor()方法创建执行器;

    ​ b、先创建 SimpleExecutor简单执行器,再判断是否开启了二级缓存,默认是开启的(使用时需要配置条件),就会去创建CacheExecutor缓存执行器

    ​ c、执行interceptorChain.pluginAll()方法,责任链设计模式,底层使用动态代理技术,使开发者可以自定义插件开发,只需要实现Interceptor接口,并指定想要拦截的方法签名即可,最后返回执行器;

    4、操作mapper接口

    ​ a、调用getMapper()方法,最终执行mapperProxyFactory.newInstance(sqlSession)方法创建代理类MapperProxy;

    ​ b、当我们调用mapper,getUser()方法的时候,就会去执行MapperProxy代理类的invoke()方法;

    ​ c、判断mapper接口是否有实现类,显然我们没有实现类,则调用cacheMapperMethod()方法去缓存中获取要代理的方法method;

    ​ d、进入cacheMapperMethod()方法先去查找缓存中有没有,没有的话将mapper配置文件中配置的SQL语句和对应的mapper接口方法进行关联并放入map缓存中,后期直接走缓存了,最后执行execute()方法;

    ​ e、执行execute()方法,最终调用selectOne()方法;

    ​ f、进入selectOne()方法,底层还是查询所有的,但是取第一个,查询多个的话会抛出异常;

    ​ g、进入selectList()方法,调用getMapperStatement()方法获取对应的SQL语句;

    ​ h、执行query()方法进行查询,判断如果开启了二级缓存并且配置了二级缓存存储介质(Redis,EhCache..)则先走二级缓存中查询数据,第一次查询是没有缓存数据的,则刷新缓存配置,清除缓存。

    ​ i、二级缓存(sessionFactory)中没有查询到数据,就回去执行BaseExecutor去查询 HashMap一级缓存中(sqlSession)是否有缓存数据,一级缓存(PerpetualCache)存放在内存中的,同理也是没有的,最后查询数据库DB

    ​ j、将从数据库查询出来的数据缓存到一级缓存中,再把一级缓存中的数据同步到二级缓存,添加到二级缓存之前先添加到getTransactionalCache的entritiesToAddOnCommit的map集合中临时缓存起来;

    ​ k、调用executor.close()方法循环迭代TransactionCache,最后将临时map缓存数据提交到二级缓存中,如果事务回滚,则会将缓存数据清除掉

    ​ l、再次查询的话,就有缓存了,会直接查询到缓存数据返回,不会去查询数据库DB

MyBatis(十一):MyBatis架构流程浅析的更多相关文章

  1. mybatis(十一)mybatis常见问题

    用注解还是用 xml 配置? 常用注解:@Insert.@Select.@Update.@Delete.@Param.@Results. @Result 在 MyBatis 的工程中,我们有两种配置 ...

  2. 浅析MyBatis(一):由一个快速案例剖析MyBatis的整体架构与运行流程

    MyBatis 是轻量级的 Java 持久层中间件,完全基于 JDBC 实现持久化的数据访问,支持以 xml 和注解的形式进行配置,能灵活.简单地进行 SQL 映射,也提供了比 JDBC 更丰富的结果 ...

  3. Spring+SpringMVC+MyBatis深入学习及搭建(十一)——SpringMVC架构

    转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6985816.html 前面讲到:Spring+SpringMVC+MyBatis深入学习及搭建(十)--My ...

  4. MyBatis原理-架构流程

    一 .MyBatis原理架构图 Mybatis的功能架构分为三层: API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库.接口层一接收到调用请求就会调用数据处理层来完成具体 ...

  5. Mybatis执行流程浅析(附深度文章推荐&面试题集锦)

    首先推荐一个简单的Mybatis原理视频教程,可以作为入门教程进行学习:点我 (该教程讲解的是如何手写简易版Mybatis) 执行流程的理解 理解Mybatis的简单流程后自己手写一个,可以解决百分之 ...

  6. mybatis(五)mybatis工作流程

    转载:https://www.cnblogs.com/wuzhenzhao/p/11103017.html 先来看一下MyBatis 的编程式使用的方法: public void testMapper ...

  7. 我们把Mybatis的功能架构分为三层:

    我们把Mybatis的功能架构分为三层: (1)API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库.接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理. (2) ...

  8. 基于spring和mybatis的简单项目流程

    Mybatis整合Spring配置 第一部分:配置Spring框架 配置SpringMVC的步骤 配置流程图 SpringMVC配置 导入包(基本包5个,1日志依赖包,2webmvc支持包) 构建一个 ...

  9. 【Mybatis】MyBatis之配置自定义数据源(十一)

    本例是在[Mybatis]MyBatis之配置多数据源(十)的基础上进行拓展,查看本例请先学习第十章 实现原理 1.扩展Spring的AbstractRoutingDataSource抽象类(该类充当 ...

随机推荐

  1. MySQL数据库系列(四)- InnoDB下的共享表空间和独立表空间详解

    一.概念 共享表空间: Innodb的所有数据保存在一个单独的表空间里面,而这个表空间可以由很多个文件组成,一个表可以跨多个文件存在,所以其大小限制不再是文件大小的限制,而是其自身的限制.从Innod ...

  2. Java 并发机制底层实现 —— volatile 原理、synchronize 锁优化机制

    本书部分摘自<Java 并发编程的艺术> 概述 相信大家都很熟悉如何使用 Java 编写处理并发的代码,也知道 Java 代码在编译后变成 Class 字节码,字节码被类加载器加载到 JV ...

  3. Netty(四)基于Netty 的简易版RPC

    3.1 RPC 概述 下面的这张图,大概很多小伙伴都见到过,这是 Dubbo 官网中的一张图描述了项目架构的演进过程 它描述了每一种架构需要的具体配置和组织形态.当网站流量很小时,只需一个应用,将所有 ...

  4. [转]论基于DSSA的软件架构设计与应用

    [摘要]   去年三月份,我所在的公司启动国网电力用户用电信息采集系统项目,我被任命为项目负责人.国网电力用户用电信息采集系统是国家电网公司坚强智能电网建设的一部分.由于公司之前为南网(主要是广东省) ...

  5. PWA All In One

    PWA All In One chrome://apps/ PWA Progressive Web App 可安装,添加到主屏 离线使用 轻量,快速 基于 Web 技术一套代码多端复用(移动端,桌面端 ...

  6. window.navigator All In One

    window.navigator All In One navigator "use strict"; /** * * @author xgqfrms * @license MIT ...

  7. ES6 arrow function vs ES5 function

    ES6 arrow function vs ES5 function ES6 arrow function 与 ES5 function 区别 this refs xgqfrms 2012-2020 ...

  8. js & replaceAll & non-global RegExp bug

    js & replaceAll https://caniuse.com/#search=replaceAll https://developer.mozilla.org/en-US/docs/ ...

  9. react-parent-child-lifecycle-order

    react-parent-child-lifecycle-order react parent child lifecycle order live demo https://33qrr.csb.ap ...

  10. React & Didact

    React & Didact A DIY guide to build your own React https://github.com/pomber/didact https://gith ...