MyBatis(12) 源码解析之SQL执行流程
一、前言
资料
- mybatis文档:https://mybatis.org/mybatis-3/index.html
- mybatis源码:https://github.com/mybatis/mybatis-3
二、mybatis是什么?
- 一款优秀的
持久层框架
,支持自定义SQL
、存储过程
以及高级映射
。 免除
了传统的JDBC代码
以及设置参数
和获取结果集
的工作。- 可以通过
XML
/注解
方式来配置和映射
原始类型
、接口
和Java POJO
为数据库中的记录。
mybatis和hibernate都属于ORM
框架
ORM是什么?
ORM对象关系映射
: 用于实现面向对象编程语言里不同类型系统数据之间的转换
,解决数据库与程序间的异构性
ex: username
字段在数据库中为VARCHAR
类型,而在Java对象中为String
类型
三、入门环境准备
这里可直接参考mybatis文档:https://mybatis.org/mybatis-3/getting-started.html
小编这里使用的是mybatis源码环境,即 将源码clone下来根据文档入门实现了一个简单的sql查询
详细代码可自行参考: https://gitee.com/zhengqingya/java-workspace
下面将通过debug一步一步探索源码,主要将围绕如图3大模块来debug
四、mybatis获取数据源
这里的root即拿到的配置文件中的内容,然后一个一个去解析加载数据
propertiesElement(root.evalNode("properties"))
:加载jdbc.properties
配置文件中数据
执行完,到environmentsElement(root.evalNode("environments"))
方法处,即已经拿到我们配置文件的数据源信息
然后进入dataSourceElement(child.evalNode("dataSource"))
再进入resolveClass
,发现通过pooled
这个key可以拿到org.apache.ibatis.datasource.pooled.PooledDataSourceFactory
回来我们可以发现获取到的这个pooled
值value,也就是org.apache.ibatis.datasource.pooled.PooledDataSourceFactory
Class类再newInstance拿到DataSourceFactory
这么一个实例
DataSourceFactory factory = (DataSourceFactory) resolveClass(type).getDeclaredConstructor().newInstance();
最终返回,即发现已经拿到了我们的dataSource
数据库源,然后通过Builder设计模式赋值给Environment
,存放到org.apache.ibatis.session.Configuration#environment
五、mybatis获取sql执行语句
首先要明白我们的sql语句是写在mapper.xml中,然后是在mybatis-config.xml
中解析,因此debug 查看org.apache.ibatis.builder.xml.XMLConfigBuilder#parseConfiguration
方法中的 mapperElement(root.evalNode("mappers"))
这里因为只有resource
,因此走如下断点处方式解析mapper
进入mapperParser.parse()
这里因此我们的sql是select语句,因此直接进入buildStatementFromContext(context.evalNodes("select|insert|update|delete"))
注意此时list中的就是我们mapper中的sql语句
然后进入statementParser.parseStatementNode()
看看mybatis拿到sql内容之后又是怎么做的呢
可以看见mybatis是将context
中的sql内容一个一个解析成临时的局部变量
再走到下面,发现解析的变量是在这里被使用,因此进入builderAssistant.addMappedStatement(...)
方法
最终可以看见这些变量是存到了MappedStatement
类中,然后传给org.apache.ibatis.session.Configuration#mappedStatements
六、mybatis操作数据库
进入configuration.newExecutor(tx, execType)
这里可以看见默认返回一个SimpleExecutor
简单执行器,以及我们的mybatis在这里默认开启一级缓存
执行完这里会返回一个DefaultSqlSession
然后调用selectOne
方法
进入selectList
这里ms
中含之前获取的sql执行语句,然后进入executor.query
这里可以看见prepareStatement
方法中拿到我们的connection
然后进入handler.query(stmt, resultHandler)
可以看到拿到了PreparedStatement
然后进入resultSetHandler.handleResultSets(ps)
进入getFirstResultSet(stmt)
方法
进入ResultSetWrapper
到这里我们就可以明白什么是ORM了!!!
用于实现面向对象编程语言里不同类型系统数据之间的转换
username
字段在数据库中为VARCHAR
类型,而在Java对象中为String
类型
最后回到org.apache.ibatis.executor.BaseExecutor#queryFromDatabase
方法处,list
中的数据也就是最后sql查询到的结果
debug结束后,最终完美拿到了我们的数据
现在再来看看这幅图,应该会更容易理解了
七、mybatis执行流程
参考:MyBatis体系结构源码解读
MyBatis(12) 源码解析之SQL执行流程相关推荐
- SharingSphere 源码解析 -- 真实SQL生成探索
SharingSphere 源码解析 – 真实SQL生成探索 简介 在上一篇文章中,我们探索了ShardingSphere JDBC Mybatis示例执行的一个大致的过程,找到了SQL处理的关键节点 ...
- mybatis源码学习篇之——执行流程分析
前言 在正式学习mybatis框架源码之前,需要先弄懂几个问题?myabtis框架是什么?为什么需要mybatis框架?使用mybatis框架带来的好处是什么? 回答这几个问题之前,我们先来看一下,之 ...
- sharding-jdbc源码解析之sql解析
2019独角兽企业重金招聘Python工程师标准>>> 说在前面 本文转自"天河聊技术"微信公众号 本次介绍的是sharding-jdbc的源码解析部分的sql解 ...
- 源码解析-偏向锁撤销流程解读
一.单个偏向锁的撤销 源码链接:http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/9ce27f0a4683/src/share/vm/runtim ...
- 详细讲解go web框架之gin框架源码解析记录及思路流程和理解
开篇 首先gin 框架是在 官方提供的net/http标准包进行的相应封装. 那么要想理解gin框架, 就要先懂一些 net/http标准包 的相关知识. 可以参考中文的 文档: https://st ...
- Glide 4.9源码解析-图片加载流程
本文Glide源码基于4.9,版本下载地址如下:Glide 4.9 前言 由于Glide源码真的很复杂,因此本文只分析和贴出与图片加载流程相关的功能以及代码.另外本文Glide源码基于4.9,与3.x ...
- 深入了解junit及Statement源码 ,了解整体执行流程
简介 junit 基于java语言的单元测试类框架 Statement 对一个单元运行的封装,每个Statement都只是执行它本身所表达的逻辑,而将其他逻辑交给下一个Statement处理,而且基本 ...
- 12.源码阅读(app启动流程-android api 26)
activity的启动流程之前已经通过源码了解了,那么app的启动流程是怎样的,从我们按下app的图标,到应用启动起来显示出画面,中间都经历了什么? 安卓是基于java的,所以和java有一定的相似性 ...
- java的jdbc看不到源码_不了解jdbc,何谈Mybatis的源码解析?
这篇文章主要用来展示jdbc的使用,是为了方便阅读MyBatis源码使用的,为源码分析做一个提前热身: 里面很多关键性的信息在MyBatis源码里面都能找到,本篇不做MyBatis源码的分析, 因为M ...
最新文章
- 如何修改Sql2005注册服务器名称 {转载}
- WIKI与BLOG殊途同归(转)
- BASIC-1_蓝桥杯_闰年判断
- 采用Lists.UpdateListItems方法更新列表项各种类型值的写法
- android 拨打电话 发送短信 权限,Android开发实现拨打电话与发送信息的方法分析...
- leetcode刷题:求旋转有序数组的最小值
- mysql里的数据输入窗口是哪个_WINDOWS下使用Mysql 中碰到的问题记录
- python 迭代器 生成器 区别_Python的生成器和迭代器之间的区别
- (三)Lucene中Index.ANALYZED分词相关
- 关于在ElasticSearch中使用now函数进行时间范围过滤查询的问题
- 搜索引擎网站登录入口|免费登录|百度登录|谷歌登录|网站收录入口
- 计算机主板维修,计算机主板维修从业技能全程通(70M)*
- cpy几天爬出密道问题
- rk3588调试之imx415摄像头
- 2017年10米分辨率全球土地覆盖产品(FROM-GLC10)Python下载爬虫
- EfficientNet B0 训练 Standford 汽车图片分类(对比ResNet34)
- 【matlab】三次埃尔米特插值与三次样条插值的实际应用代码
- vue3的pdf文件下载
- c语言数组124048,根据GPS经纬度判断当前所属的市区
- vue为什么需要nodejs 的环境
热门文章
- cad四边形展开lisp_CAD的LISP功能函数一览表
- Multisim电路分析仿真-RLC串联电路的时域
- Frp内网穿透(四)安卓设备内网穿透
- 热门图表软件推荐,哪款更功能更强大?
- 如何在matlab中建立水箱模型_在MATLAB中实现水箱液位控制系统的设计
- Python爬虫实战,pymongo模块,Python实现数据分析国外人为啥喜欢李子柒
- 实验项目:用IMAIL构建企业邮件服务器
- 看完此帖你100%会感动的流泪[感动]
- 手写字符识别入门学习记录(1)
- 道道通导航linux升级,道道通导航升级2020冬季版