一、前言

资料

  1. mybatis文档:https://mybatis.org/mybatis-3/index.html
  2. mybatis源码:https://github.com/mybatis/mybatis-3

二、mybatis是什么?

  1. 一款优秀的持久层框架,支持自定义SQL存储过程以及高级映射
  2. 免除了传统的JDBC代码以及设置参数获取结果集的工作。
  3. 可以通过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.PooledDataSourceFactoryClass类再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执行流程相关推荐

  1. SharingSphere 源码解析 -- 真实SQL生成探索

    SharingSphere 源码解析 – 真实SQL生成探索 简介 在上一篇文章中,我们探索了ShardingSphere JDBC Mybatis示例执行的一个大致的过程,找到了SQL处理的关键节点 ...

  2. mybatis源码学习篇之——执行流程分析

    前言 在正式学习mybatis框架源码之前,需要先弄懂几个问题?myabtis框架是什么?为什么需要mybatis框架?使用mybatis框架带来的好处是什么? 回答这几个问题之前,我们先来看一下,之 ...

  3. sharding-jdbc源码解析之sql解析

    2019独角兽企业重金招聘Python工程师标准>>> 说在前面 本文转自"天河聊技术"微信公众号 本次介绍的是sharding-jdbc的源码解析部分的sql解 ...

  4. 源码解析-偏向锁撤销流程解读

    一.单个偏向锁的撤销 源码链接:http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/file/9ce27f0a4683/src/share/vm/runtim ...

  5. 详细讲解go web框架之gin框架源码解析记录及思路流程和理解

    开篇 首先gin 框架是在 官方提供的net/http标准包进行的相应封装. 那么要想理解gin框架, 就要先懂一些 net/http标准包 的相关知识. 可以参考中文的 文档: https://st ...

  6. Glide 4.9源码解析-图片加载流程

    本文Glide源码基于4.9,版本下载地址如下:Glide 4.9 前言 由于Glide源码真的很复杂,因此本文只分析和贴出与图片加载流程相关的功能以及代码.另外本文Glide源码基于4.9,与3.x ...

  7. 深入了解junit及Statement源码 ,了解整体执行流程

    简介 junit 基于java语言的单元测试类框架 Statement 对一个单元运行的封装,每个Statement都只是执行它本身所表达的逻辑,而将其他逻辑交给下一个Statement处理,而且基本 ...

  8. 12.源码阅读(app启动流程-android api 26)

    activity的启动流程之前已经通过源码了解了,那么app的启动流程是怎样的,从我们按下app的图标,到应用启动起来显示出画面,中间都经历了什么? 安卓是基于java的,所以和java有一定的相似性 ...

  9. java的jdbc看不到源码_不了解jdbc,何谈Mybatis的源码解析?

    这篇文章主要用来展示jdbc的使用,是为了方便阅读MyBatis源码使用的,为源码分析做一个提前热身: 里面很多关键性的信息在MyBatis源码里面都能找到,本篇不做MyBatis源码的分析, 因为M ...

最新文章

  1. 如何修改Sql2005注册服务器名称 {转载}
  2. WIKI与BLOG殊途同归(转)
  3. BASIC-1_蓝桥杯_闰年判断
  4. 采用Lists.UpdateListItems方法更新列表项各种类型值的写法
  5. android 拨打电话 发送短信 权限,Android开发实现拨打电话与发送信息的方法分析...
  6. leetcode刷题:求旋转有序数组的最小值
  7. mysql里的数据输入窗口是哪个_WINDOWS下使用Mysql 中碰到的问题记录
  8. python 迭代器 生成器 区别_Python的生成器和迭代器之间的区别
  9. (三)Lucene中Index.ANALYZED分词相关
  10. 关于在ElasticSearch中使用now函数进行时间范围过滤查询的问题
  11. 搜索引擎网站登录入口|免费登录|百度登录|谷歌登录|网站收录入口
  12. 计算机主板维修,计算机主板维修从业技能全程通(70M)*
  13. cpy几天爬出密道问题
  14. rk3588调试之imx415摄像头
  15. 2017年10米分辨率全球土地覆盖产品(FROM-GLC10)Python下载爬虫
  16. EfficientNet B0 训练 Standford 汽车图片分类(对比ResNet34)
  17. 【matlab】三次埃尔米特插值与三次样条插值的实际应用代码
  18. vue3的pdf文件下载
  19. c语言数组124048,根据GPS经纬度判断当前所属的市区
  20. vue为什么需要nodejs 的环境

热门文章

  1. cad四边形展开lisp_CAD的LISP功能函数一览表
  2. Multisim电路分析仿真-RLC串联电路的时域
  3. Frp内网穿透(四)安卓设备内网穿透
  4. 热门图表软件推荐,哪款更功能更强大?
  5. 如何在matlab中建立水箱模型_在MATLAB中实现水箱液位控制系统的设计
  6. Python爬虫实战,pymongo模块,Python实现数据分析国外人为啥喜欢李子柒
  7. 实验项目:用IMAIL构建企业邮件服务器
  8. 看完此帖你100%会感动的流泪[感动]
  9. 手写字符识别入门学习记录(1)
  10. 道道通导航linux升级,道道通导航升级2020冬季版