MyBatis核心流程三大阶段之数据读写阶段
啃下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对于结果集封装的步骤:
创建multipleResults集合,保存最终返回的结果。
取出第一个结果集
获取对应的resultMap
根据resultMap转化结果集,转换成目标对象后添加到multipleResults集合;
resultset.close()关闭结果集,将multipleResults集合返回
2.sqlSession查询流程图和Executor内部调用流程图
sqlSession查询流程图:
Executor内部调用流程图:
至此MyBatis核心流程最后一个阶段:数据读写阶段完成。
MyBatis核心流程三大阶段之数据读写阶段相关推荐
- MyBatis核心流程以及工作原理
MyBatis核心对象 根据以下这四大核心对象,我们就能理清MyBatis的工作原理. SqlSession对象,该对象中包含了执行SQL语句的所有方法.类似于JDBC里面的Connection. E ...
- 百亿数据分库分表核心流程详解
前言 俗话说:面试造火箭,入职拧螺丝.尽管99.99%的业务都不需要用到分库分表,但是分库分表还是频繁出现在大厂的面试中. 分库分表涉及到的内容非常多,有很多细节,如果在面试中被问到了,既是挑战,也是 ...
- 大数据WEB阶段Mybatis(二)
Mybatis(二) 零.目录 Mybatis接口形式 Mybatis整合Spring Mybatis的缓存机制 手动封装结果集 一对一表操作 一对多表操作 多对多表操作 SpringMVC . Sp ...
- 大数据WEB阶段Mybatis(一)
Mybatis(一) 零.目录 Mybatis介绍 Mybatis入门案例 增删改查练习 映射文件中取值问题 Mybatis中单值传递和多值传递问题 sql语句的复用 别名标签 动态更新 动态查询 动 ...
- CAP原理,分布式一致性算法,两阶段提交,三阶段提交,Paxos,Raft,zookeeper的选主过程,zab协议,顺序一致性,数据写入流程,节点状态,节点的角色
我们知道,一般在分布式应用都有CAP准则: C Consistency, 一致性,分布式中的各个节点数据保持一致 A availability 可用性,任何时刻,分布式集群总是能够提供服务 P par ...
- 15-Hbase深入理解数据读写流程、数据刷写、合并、切分和表设计原则
8.6 HBase读写流程⭐️ 对于HBase框架,读比写慢(与其他框架相反) 8.6.1 公共流程(三层索引) 对于数据对应的Region位置在哪里的问题的提出 HBase中单表的数据量通常可以达到 ...
- 2021年大数据Hadoop(十):HDFS的数据读写流程
2021大数据领域优质创作博客,带你从入门到精通,该博客每天更新,逐渐完善大数据各个知识体系的文章,帮助大家更高效学习. 有对大数据感兴趣的可以关注微信公众号:三帮大数据 目录 HDFS的数据读写流程 ...
- 嵌入式linux文件系统格式,嵌入式Linux的文件系统分区及数据读写方法与流程
本发明涉及Linux系统的数据存储管理领域,特别是涉及一种基于NANDFlash存储器和UBIFS文件系统的嵌入式Linux的文件系统分区及数据读写方法. 背景技术: ::目前Linux操作系统由于源 ...
- 大数据技术之大数据基础阶段考试题(二)
文章目录 一 .Zookeeper 1 请简述ZooKeeper的选举机制 假设有五台服务器组成的zookeeper集群,它们的id从1-5,同时它们都是最新启动的,也就是没有历史数据,在存放数据量这 ...
- 大数据学习阶段,每天2小时学习,成就不一样的自己
前言阶段:什么是大数据?什么是人工智能? 本阶段不需要编程,很多人听过大数据,听过人工智能,听过数据挖掘.但是几乎都有疑问:什么是大数据?什么是人工智能?大数据和人工智能能做什么?等等.这一阶段主要是 ...
最新文章
- canvas-color的几种设置
- Enthought Canopy中第三方软件包的安装(package manager中不含的包)
- Facebook、阿里等大佬现身说法,NLP是否被高估了?
- Python简介及环境搭建
- Unity打包APK细节(翻译自官网)
- 苹果隐私部门负责人:在iPhone上侧载应用会减少用户选择
- Linux 命令(95)—— test 命令
- python的setheading什么意思_用Python告诉你什么是佩奇
- 创建一个HashMap 集合,存储省份下的城市,key是为省份 value 是为该省份下的城市
- Tecplot 360 安装后弹出“Is your Tecplot 360 EX liense valid?”解决方法
- 基于 Vue 2.0 的 UI 组件库 KUI for Vue
- 这样的国企,不去也罢
- 智慧天气系统 - 可视化大屏(Echarts)管理系统(HTTP(S)协议)物联网平台(MQTT协议)
- 《C++ 笔记》 Part5 C++ 资源大全中文版
- 加载property配置文件
- 使用python下载网易云课堂中Andrew Ng的机器学习课程
- 科技云报道:超融合遍地开花,用户离“云计算自由”却依然很远?
- kali系统破解wifi密码
- 流水账php,11-12流水账
- HTML标记【标记br和p的使用】!
热门文章
- python url转码_URL转码,encodeURI,encodeURIComponent — 在线工具
- onenote打开闪退平板_ipad pro 11英寸。onenote闪退 无法使用
- Mybatis提高查询效率的方式
- 大数据司法时代的立言、立功与立德
- 汪磊老师整理的前端进阶课程目录
- 拼音字母匹配排序php,小程序实现仿通讯录,拼音字母排序
- css鼠标变成小手(css中鼠标悬停是为小手)
- Array 常用函数
- book mac pro怎么重装系统_MacBook Pro怎么重装系统 MacBook Pro重装系统教程
- 2 数据可视化大屏 - 布局