读源码【读mybatis的源码的思路】

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: 读源码【读mybatis的源码的思路】

✿ 需要掌握的编译器知识

★ 编译器为eclipse为例子

  • 调试准备工作(步骤:Window -> Show View -》...):
    □ 打开调试断点Breakpoint:

35.png


□ 打开变量监视:


36.png


要看一个方法的内部细节,按f5,进入


image.png


放行操作,可以快速跳到下一个断点的位置【在目标位置上打个断点】,然后按f8


image.png


观察方法的细节(执行流程),一步一步走,按f6


image.png



去除掉所有断点(编译器是eclipse)


image.png



□ 注意看开始标记的执行位置对不对


image.png


  • f5调试的方式进入【若进入的是不相干的,按f7返回,再按f5进入一次
    举例:
User user = mapper.get(1L); //在这里打一个断点进入,会先进入Long类,因为执行顺序是(1L)先执行呀,所以先进入它之后,再执行get方法
  • 按ctr 和 按调试的f5的区别:
    □ ctr:是进入“被选中的代码(类、接口、方法)”的定义的位置【强调点是代码的定义
    □ f5:是对于当前代码按执行的先后顺序进行执行,进入、执行它的内部【强调点是代码的执行
  • 按ctr 结合鼠标, 可以知道代码下一步的去向(按ctr要注意的细节:ctr默认进入的是被选中的代码的定义,不是实现过程,进入之后发现没看到什么有帮助理解的代码,返回返回按住ctr,选择实现(若是有多个实现,不知道选哪个,可以通过调试f5进入),再按鼠标进入。


42.png


43.png


重新开始调试细节:

(1)关闭上一次调试

(2)点击 开始调试之前,保留开始位置的断点前面的√,其他断点前面的√先去掉(开始调试之后才√回来)



0.png



进入一个方法后了解到方法的细节,想返回接着往下执行,按f7 返回 【返回按f7

一般在深入了解某个模块之后,可以按返回,返回。。。然后接着了解下一个模块


1.png


✿ 读源码的思路

1、重点理解执行逻辑(执行过程可以按control进入方法或类,理解下一步去向后,光标回到当前位置【快捷键是alt+←】)

2、看源码过程理清思路,异常相关的(error、exception、throw),让代码更加健硕的细节可以忽略;栈相关的stack,底层的可以忽略

3、在代码中,看到选择分支的话,可以观察变量的值(判断条件)知道要进入哪个分支

4、在代码中,看到不理解的代码,可以先往下执行,然后通过观察变量的值进行理解【还可结合官网进行理解】

5、读取流、加载资源、绑定命名空间、参数转化不是重点

6、构造构造器不是重点,重点是看 构造器的构造过程

7、构造解析器不是重点,重点是看 解析器的解析过程

8、创建了子类要注意:什么类型的子类?当子类有封装的父类或兄弟类时候,注意封装的父类或兄弟类是什么类型的?




1、重点理解执行逻辑(执行过程可以按control进入方法或类,理解下一步去向后,光标回到当前位置【快捷键是alt+←】)

  • 所以阅读源码,咱了解到:创建了一个SqlSessoinFactory会话工厂对象是通过默认的SqlSessoinFactory创建的,在创建的时候需要传入一个配置对象【即创建会话工厂对象的时候还创建了一个配置对象】,至此,研究一下配置对象的创建过程。


image.png


2、看源码过程理清思路,异常相关的(error、exception、throw),让代码更加健硕的细节可以忽略;栈相关的stack,底层的可以忽略


3.png

4.png

5.png

6.png7.png


3、在代码中,看到选择分支的话,可以观察变量的值(判断条件)知道要进入哪个分支


8.png


4、在代码中,看到不理解的代码,可以先往下执行,然后通过观察变量的值进行理解【还可以结合官网进行理解】


9.png


5、读取流、加载资源、绑定命名空间、参数转化不是重点


10.png

11.png

12.png


6、构造构造器不是重点,重点是看构造器的构造过程


13.png


7、构造解析器不是重点,重点是看解析器的解析过程


14.png

15.png

16.png


8、创建了子类要注意:什么类型的子类?当子类有封装的父类或兄弟类时候,注意封装的父类或兄弟类是什么类型的?

  • Executor
  • CachingExecutor(Simple) 带有缓存的执行器


17.png


✿ 读mybatis的源码的思路

■ 1、 阅读源码的过程,应该阅读哪一个,哪一个是阅读重点呢?

  • 阅读源码构建会话工厂对象的源码,咱了解到:创建了一个SqlSessoinFactory会话工厂对象是通过默认的SqlSessoinFactory创建的,在创建的时候需要传入一个配置对象【即创建会话工厂对象的时候还创建了一个配置对象】,至此,研究一下配置对象的创建过程。

image.png


  • 阅读源码构建会话工厂对象的源码,咱了解到:创建一个sqlSession会话对象是通过默认的sqlSession,在创建的时候需要传入三个参数,重点是观察哪个呢?

□ configuration 配置对象(在阅读会话工厂对象构建的源码的时候咱就了解过它了,不是重点)

□ executor 执行器(重点,因为在return 会话对象之前构建了executor执行器

□ autoCommit (是否提交,布尔值,不是重点)


19.png


结合理解逻辑,还有return的提示作用,知道阅读重点是list的过程


image.png


■ 2、 阅读源码mybatis操作数据库的过程:

/* 测试查询 */
  @Test
  public void testGet() throws IOException {
    // 1、从classpath路径加载mybatis全局配置文件mybatis-config.xml
    InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
    // 2、创建SqlSessoinFactory会话工厂对象,好比连接池DataSource
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    SqlSessionFactory factory = builder.build(in);
    // 3、创建SqlSession会话对象,好比连接对象Connection
    SqlSession session = factory.openSession();
    // 4、获取mapper对象
    UserMapper mapper = session.getMapper(UserMapper.class);
    //执行sql操作
    User user = mapper.get(1L);
    System.out.println(user);
    // 5、关闭资源
    session.close();
  }

(1)创建SqlSessoinFactory会话工厂对象

  • 查看源码得知,表名上是创建了一个SqlSessoinFactory会话工厂对象, 实际上在创建SqlSessoinFactory会话工厂对象的时候还创建了一个全局配置对象。咱还顺带看了一下全局配置的创建过程啦

image.png


(2)创建SqlSessoin会话对象

  • 查看源码得知,表名上是创建了一个SqlSessoin会话对象, 实际上在创建SqlSessoin会话对象的时候还创建了一个全执行器对象。咱还顺带看了一下执行器的创建过程啦
  • 执行器对象ExecutorCachingExcutor(Simple)带有缓存的执行器】,是mybatis的调度中心,负责sql的生成和查询缓存维护。在创建SqlSessoin会话对象创建,会执行pluginAll方法

22.png


(3)创建mapper对象

  • 查看源码得知,创建mapper对象, 实际上通过jdk的代理机制创建了一个mapper的代理对象。

23.png


24.png


(4) 执行sql操作:mapper.get(1L);

  • 先判断传入的方法类型,不是Object类型,就使用映射方法进行执行

25.png


执行的时候会根据元素类型进行选择


226.png


咱执行mapper.get(1L)实际上是会话对象调用selectOne方法


26.png


selectOne 返回一个集合list,观察selectList


27.png


映射语句mapperStatement封装了元素的信息


28.png

在selectList方法看到执行器调用查询方法


29.png



  • 发现执行查询的过程,先经过CachingExcutor(带有二级缓存的执行器),先从二级缓存中寻找是否有数据

30.png


发现执行查询的过程,经过BaseExcutor(底层的执行器),先从一级缓存localCache中寻找是否有数据,若是没有在从数据库中查询


31.png


从数据库查询,是简单的执行器,调用doQuery方法


32.png


  • 构建语句处理器对象
    33.png

  • 构建RoutingStatementHandler语句处理器对象
    34.png


  • 构建PreparedStatementHandler预编译语句处理器对象
    35.png
  • 构建ParameterHandler参数处理器对象、构建ParameterHandler参数处理器对象
    36.png


  • ★ Statement(PreparedStatement 预编译语句对象)创建对象之前,先创建参数处理器和结果处理器
    □ ParamterHandler 参数处理器,先把用户传入的参数转成JDBC需要的参数值,在创建对象之前,会执行pluginAll方法
    □ ResultSetHandler 结果集处理器,把结果集中的数据封装到list集合,在创建对象之前,会执行pluginAll方法


    37.png
  • 网络异常,图片无法展示
    |
  • 38.png

  • 实例化一个语句对象
    40.png


。。。


✿ 总结阅读mybatis执行sql的源码中的核心对象:

  • InterceptorChaiin 拦截器链,多个拦截器合成
  • Configuration 全局配置对象,封装了所有的配置信息
  • Executor 执行器,myBatis的调度中心,负责sql生成和查询缓存维护,在创建sqlSession对象之前。创建ok之后,会执行pluginAll方法
  • BaseExecutor 底层的执行器,先从一级缓存中查询,若没有,则到数据库中查询
  • CachingExcutor(Simple) 带有二级缓存的执行器,先去二级缓存中寻找是否有数据
  • MappedStatement 映射语句对象,封装了一个元素节点(insert|delete|update|select)的信息
  • StatementHandler 语句处理器,封装了JDBC的DML/DQL操作,参数设置,在创建对象时,执行pluginAll方法
  • RoutingStatement
  • TypeHandler 类型转化器,把java类型和JDBC类型做相互转化操作,参数处理器、结果集处理器都会用到它。


■ 在创建StatementHandler 创建对象之前,先创建参数处理器和结果集处理器

□ ParameterHandler 参数处理器,把用户传入的参数转化为JDBC需要的参数值,在创建对象时,执行 pluginAll方法

□ ResultSetrHandler 结果集处理器,在结果集中的数据封装到List集合,在创建对象时,执行 pluginAll方法



✿ 读的源码需要掌握的单词

  • map 映射       mapper 映射器
  • factory 工厂
  • build 构建
  • config 配置
  • parse 解析     parser 解析器      parsed 已解析的      parseConfiguration 解析配置
  • interceptor 拦截器
  • plugin “安装[增强]”、插件
  • proxy 代理
  • prepared 预编译的 callable 存储的
  • statment 语句对象      preparedStatement 预编译语句对象     callableStatement 存储的语句对象
  • cursor 光标
  • instantiate 实例化      instantiateStatement 实例化语句对象
  • handler 处理器      typeHandler 类型处理器
  • row 行
目录
相关文章
|
5月前
|
安全 Java 应用服务中间件
阿里技术官架构使用总结:Spring+MyBatis源码+Tomcat架构解析等
分享Java技术文以及学习经验也有一段时间了,实际上作为程序员,我们都清楚学习的重要性,毕竟时代在发展,互联网之下,稍有一些落后可能就会被淘汰掉,因此我们需要不断去审视自己,通过学习来让自己得到相应的提升。
|
9天前
|
SQL XML Java
mybatis-源码深入分析(一)
mybatis-源码深入分析(一)
|
2月前
|
XML Java 数据库连接
mybatis源码研究、搭建mybatis源码运行的环境
这篇文章详细介绍了如何搭建MyBatis源码运行的环境,包括创建Maven项目、导入源码、添加代码、Debug运行研究源码,并提供了解决常见问题的方法和链接到搭建好的环境。
mybatis源码研究、搭建mybatis源码运行的环境
|
2月前
|
Web App开发 前端开发 关系型数据库
基于SpringBoot+Vue+Redis+Mybatis的商城购物系统 【系统实现+系统源码+答辩PPT】
这篇文章介绍了一个基于SpringBoot+Vue+Redis+Mybatis技术栈开发的商城购物系统,包括系统功能、页面展示、前后端项目结构和核心代码,以及如何获取系统源码和答辩PPT的方法。
|
2月前
|
供应链 前端开发 Java
服装库存管理系统 Mybatis+Layui+MVC+JSP【完整功能介绍+实现详情+源码】
该博客文章介绍了一个使用Mybatis、Layui、MVC和JSP技术栈开发的服装库存管理系统,包括注册登录、权限管理、用户和货号管理、库存管理等功能,并提供了源码下载链接。
服装库存管理系统 Mybatis+Layui+MVC+JSP【完整功能介绍+实现详情+源码】
|
2月前
|
缓存 Java 数据库连接
我要手撕mybatis源码
该文章深入分析了MyBatis框架的初始化和数据读写阶段的源码,详细阐述了MyBatis如何通过配置文件解析、建立数据库连接、映射接口绑定、动态代理、查询缓存和结果集处理等步骤实现ORM功能,以及与传统JDBC编程相比的优势。
我要手撕mybatis源码
|
5月前
|
Java 数据库连接 mybatis
mybatis简单案例源码详细【注释全面】——实体层(User.java)
mybatis简单案例源码详细【注释全面】——实体层(User.java)
|
5月前
|
SQL Java 数据库连接
深入源码:解密MyBatis数据源设计的精妙机制
深入源码:解密MyBatis数据源设计的精妙机制
85 1
深入源码:解密MyBatis数据源设计的精妙机制
|
5月前
|
SQL 缓存 Java
|
5月前
|
XML Java 数据库连接
探秘MyBatis:手写Mapper代理的源码解析与实现
探秘MyBatis:手写Mapper代理的源码解析与实现
48 1