啃下MyBatis源码系列目录

啃下MyBatis源码 - 为什么要看MyBatis源码及源码结构

啃下MyBatis源码 - org.apache.ibatis.logging包源码分析

啃下MyBatis源码 - org.apache.ibatis.datasource包源码分析

啃下MyBatis源码 - org.apache.ibatis.cache包源码分析

啃下MyBatis源码 - MyBatis核心流程三大阶段之初始化阶段

啃下MyBatis源码 - MyBatis核心流程三大阶段之代理阶段(binding模块分析)

啃下MyBatis源码 - MyBatis核心流程三大阶段之数据读写阶段

啃下MyBatis源码 - MyBatis面试题总结

--------------------------------------------------------------------------------------------------------------------------

啃下MyBatis源码 - MyBatis核心流程三大阶段之数据读写阶段

1.MyBatis是怎样的封装jdbc操作的

2.sqlSession查询流程图和Executor内部调用流程图

--------------------------------------------------------------------------------------------------------------------------

1.MyBatis是怎样的封装jdbc操作的

我们先来回忆一下jdbc代码:

//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接conn
Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123");
//3.创建查询接口
Statement sta= con.createStatement();
//4.执行SQL,返回结果集
ResultSet rs= sta.executeQuery("SELECT * FROM `user`");
//5.对结果集数据进行操作
User user = new User();
user.setUserName(String.valueOf(rs.getObject(1)));

其中第一步加载驱动在MyBatis的初始化阶段就已经完成了,数据读写阶段就是处理sqlSession.executeQuery的阶段,对应JDBC第二步获取连接开始,到返回结果集封装对象结束。那MyBatis究竟是怎样封装JDBC操作的呢?我们先从sqlSession的默认实现DefaultSqlSession开始入手:

可以看到该类包含一个核心组件Executor(执行器),查询相关操作最终都借助该组件实现,那么我们来看一下Executor的关系类图:

BaseExecutor:基础抽象类,实现了executor接口的大部分方法,主要提供了缓存管理和事务管理的能力,使用了模板模式,doUpdate,doQuery,doQueryCursor 等方法的具体实现交给不同的子类进行实现

CachingExecutor:直接实现Executor接口,使用装饰器模式提供二级缓存能力。先从二级缓存查,缓存没有命中再从数据库查,最后将结果添加到缓存中。如果在xml文件中配置了cache节点,则会创建CachingExecutor。

BatchExecutor:BaseExecutor具体子类实现,在doUpdate方法中,提供批量执行多条SQL语句的能力;

SimpleExecutor:BaseExecutor具体子类实现且为默认配置,在doQuery方法中使用PrepareStatement对象访问数据库, 每次访问都要创建新的 PrepareStatement对象;

       ReuseExecutor:BaseExecutor具体子类实现,与SimpleExecutor不同的是,在doQuery方法中,使用预编译PrepareStatement对象访问数据库,访问时,会重用缓存中的statement对象,而不是每次都创建新的PrepareStatement。

       一下子丢出来这么多执行器有点蒙,没关系我们跟进一个查询流程走下来就清楚了。首先从DefaultSqlSession开始,我们调用的sqlSession.selectList方法:

       可以看到只有BaseExecutor和CachingExecutor两个类重写了query方法,而CachingExecutor类前面也说过,在Configuration类初始化的时候如果在XML中配置了<cache>节点的话,则会用装饰器模式对基础执行器进行增强,使其拥有二级缓存能力,并且我们也可以看到在初始化Executor时是通过设定的类型来决定初始化哪一个执行器子类。

       好的我们继续跟进BaseExecutor的query()方法:

       可以看到首先通过MappedStatement拿到对应的SQL信息BoundSql,再封装一级缓存值CacheKey,具体的查询为先从一级缓存拿,如果一级缓存为空,就从数据库加载数据,具体从数据库查询的方法源码:

       我们跟进默认实现SimpleExecutor的doQuery方法:

       这段代码有两点值得我们注意,一个是prepareStatement(handler, ms.getStatementLog());这个方法,我们跟进去会发现:

       终于找到了我们熟悉的JDBC代码,获取Connection,创建Statement查询接口;再一个是我们看到了四个新面孔,四种不同的处理器,一起来看下StatementHandler体系结构类图:

       BaseStatementHandler: 所有子类的抽象父类,定义了初始化statement的操作顺序,由具体子类实例化不同的statement

       CallableStatementHandler:调用存储过程

       PreparedStatementHandler:使用预编译PrepareStatement对象访问数据库

       RoutingStatementHandler:Excutor组件真正实例化的子类,使用静态代理模式,根据上下文决定创建哪个具体实体类

       SimpleStatementHandler:直接使用statement对象访问数据库,无须参数化

RoutingStatementHandler类源码,很清晰的静态代理

       接上文调用SimpleStatementHandler的query方法:

     jdbc的execute()方法也找到了,最后借助DefaultResultSetHandler对数据库返回的结果集进行封装,返回用户指定的实体类型。handleResultSets()方法部分源码:

     处理结果集的过程略复杂,这里只简单的梳理下MyBaits对于结果集封装的步骤:

  1. 创建multipleResults集合,保存最终返回的结果。

  2. 取出第一个结果集

  3. 获取对应的resultMap

  4. 根据resultMap转化结果集,转换成目标对象后添加到multipleResults集合;

  5. resultset.close()关闭结果集,将multipleResults集合返回

2.sqlSession查询流程图和Executor内部调用流程图

sqlSession查询流程图:

Executor内部调用流程图:

     至此MyBatis核心流程最后一个阶段:数据读写阶段完成。

MyBatis核心流程三大阶段之数据读写阶段相关推荐

  1. MyBatis核心流程以及工作原理

    MyBatis核心对象 根据以下这四大核心对象,我们就能理清MyBatis的工作原理. SqlSession对象,该对象中包含了执行SQL语句的所有方法.类似于JDBC里面的Connection. E ...

  2. 百亿数据分库分表核心流程详解

    前言 俗话说:面试造火箭,入职拧螺丝.尽管99.99%的业务都不需要用到分库分表,但是分库分表还是频繁出现在大厂的面试中. 分库分表涉及到的内容非常多,有很多细节,如果在面试中被问到了,既是挑战,也是 ...

  3. 大数据WEB阶段Mybatis(二)

    Mybatis(二) 零.目录 Mybatis接口形式 Mybatis整合Spring Mybatis的缓存机制 手动封装结果集 一对一表操作 一对多表操作 多对多表操作 SpringMVC . Sp ...

  4. 大数据WEB阶段Mybatis(一)

    Mybatis(一) 零.目录 Mybatis介绍 Mybatis入门案例 增删改查练习 映射文件中取值问题 Mybatis中单值传递和多值传递问题 sql语句的复用 别名标签 动态更新 动态查询 动 ...

  5. CAP原理,分布式一致性算法,两阶段提交,三阶段提交,Paxos,Raft,zookeeper的选主过程,zab协议,顺序一致性,数据写入流程,节点状态,节点的角色

    我们知道,一般在分布式应用都有CAP准则: C Consistency, 一致性,分布式中的各个节点数据保持一致 A availability 可用性,任何时刻,分布式集群总是能够提供服务 P par ...

  6. 15-Hbase深入理解数据读写流程、数据刷写、合并、切分和表设计原则

    8.6 HBase读写流程⭐️ 对于HBase框架,读比写慢(与其他框架相反) 8.6.1 公共流程(三层索引) 对于数据对应的Region位置在哪里的问题的提出 HBase中单表的数据量通常可以达到 ...

  7. 2021年大数据Hadoop(十):HDFS的数据读写流程

    2021大数据领域优质创作博客,带你从入门到精通,该博客每天更新,逐渐完善大数据各个知识体系的文章,帮助大家更高效学习. 有对大数据感兴趣的可以关注微信公众号:三帮大数据 目录 HDFS的数据读写流程 ...

  8. 嵌入式linux文件系统格式,嵌入式Linux的文件系统分区及数据读写方法与流程

    本发明涉及Linux系统的数据存储管理领域,特别是涉及一种基于NANDFlash存储器和UBIFS文件系统的嵌入式Linux的文件系统分区及数据读写方法. 背景技术: ::目前Linux操作系统由于源 ...

  9. 大数据技术之大数据基础阶段考试题(二)

    文章目录 一 .Zookeeper 1 请简述ZooKeeper的选举机制 假设有五台服务器组成的zookeeper集群,它们的id从1-5,同时它们都是最新启动的,也就是没有历史数据,在存放数据量这 ...

  10. 大数据学习阶段,每天2小时学习,成就不一样的自己

    前言阶段:什么是大数据?什么是人工智能? 本阶段不需要编程,很多人听过大数据,听过人工智能,听过数据挖掘.但是几乎都有疑问:什么是大数据?什么是人工智能?大数据和人工智能能做什么?等等.这一阶段主要是 ...

最新文章

  1. canvas-color的几种设置
  2. Enthought Canopy中第三方软件包的安装(package manager中不含的包)
  3. Facebook、阿里等大佬现身说法,NLP是否被高估了?
  4. Python简介及环境搭建
  5. Unity打包APK细节(翻译自官网)
  6. 苹果隐私部门负责人:在iPhone上侧载应用会减少用户选择
  7. Linux 命令(95)—— test 命令
  8. python的setheading什么意思_用Python告诉你什么是佩奇
  9. 创建一个HashMap 集合,存储省份下的城市,key是为省份 value 是为该省份下的城市
  10. Tecplot 360 安装后弹出“Is your Tecplot 360 EX liense valid?”解决方法
  11. 基于 Vue 2.0 的 UI 组件库 KUI for Vue
  12. 这样的国企,不去也罢
  13. 智慧天气系统 - 可视化大屏(Echarts)管理系统(HTTP(S)协议)物联网平台(MQTT协议)
  14. 《C++ 笔记》 Part5 C++ 资源大全中文版
  15. 加载property配置文件
  16. 使用python下载网易云课堂中Andrew Ng的机器学习课程
  17. 科技云报道:超融合遍地开花,用户离“云计算自由”却依然很远?
  18. kali系统破解wifi密码
  19. 流水账php,11-12流水账
  20. HTML标记【标记br和p的使用】!

热门文章

  1. python url转码_URL转码,encodeURI,encodeURIComponent — 在线工具
  2. onenote打开闪退平板_ipad pro 11英寸。onenote闪退 无法使用
  3. Mybatis提高查询效率的方式
  4. 大数据司法时代的立言、立功与立德
  5. 汪磊老师整理的前端进阶课程目录
  6. 拼音字母匹配排序php,小程序实现仿通讯录,拼音字母排序
  7. css鼠标变成小手(css中鼠标悬停是为小手)
  8. Array 常用函数
  9. book mac pro怎么重装系统_MacBook Pro怎么重装系统 MacBook Pro重装系统教程
  10. 2 数据可视化大屏 - 布局