mybatis源码学习-2-项目结构
写在前面,这里会有很多借鉴的内容,有以下三个原因
- 本博客只是作为本人学习记录并用以分享,并不是专业的技术型博客
- 笔者是位刚刚开始尝试阅读源码的人,对源码的阅读流程乃至整体架构并不熟悉,观看他人博客可以帮助我快速入门
- 如果只是笔者自己观看,难免会有很多弄不懂乃至理解错误的地方,观看他人的体会能有效改善这个问题
1. 概述
本文主要分享 MyBatis 的项目结构。
希望通过本文能让胖友对 MyBatis 的整体项目有个简单的了解。另外,http://www.mybatis.org 提供了 MyBatis 非常不错的中文文档。
2. 代码统计
这里先分享一个小技巧。笔者在开始源码学习时,会首先了解项目的代码量。
第一种方式,使用 IDEA Statistic 插件,统计整体代码量。
我们可以粗略的看到,总的代码量在 21017行。还是在可接受的范围。
3. 整体架构
MyBatis 的整体架构分为三层:
- 基础支持层
- 核心处理层
- 接口层
3.1 基础支持层
基础支持层,包含整个 MyBatis 的基础模块,这些模块为核心处理层的功能提供了良好的支撑。
3.1.1 反射模块
对应 reflection
包。
Java 中的反射虽然功能强大,但对大多数开发人员来说,写出高质量的反射代码还是 有一定难度的。MyBatis 中专门提供了反射模块,该模块对 Java 原生的反射进行了良好的封装,提了更加简洁易用的 API,方便上层使调用,并且对反射操作进行了一系列优化,例如缓存了类的元数据,提高了反射操作的性能。
3.1.2 类型模块
对应 type
包。
① MyBatis 为简化配置文件提供了别名机制,该机制是类型转换模块的主要功能之一。
② 类型转换模块的另一个功能是实现 JDBC 类型与 Java 类型之间的转换,该功能在为 SQL 语句绑定实参以及映射查询结果集时都会涉及:
- 在为 SQL 语句绑定实参时,会将数据由 Java 类型转换成 JDBC 类型。
- 而在映射结果集时,会将数据由 JDBC 类型转换成 Java 类型。
3.1.3 日志模块
对应 logging
包。
无论在开发测试环境中,还是在线上生产环境中,日志在整个系统中的地位都是非常重要的。良好的日志功能可以帮助开发人员和测试人员快速定位 Bug 代码,也可以帮助运维人员快速定位性能瓶颈等问题。目前的 Java 世界中存在很多优秀的日志框架,例如 Log4j、 Log4j2、Slf4j 等。
MyBatis 作为一个设计优良的框架,除了提供详细的日志输出信息,还要能够集成多种日志框架,其日志模块的一个主要功能就是集成第三方日志框架。
3.1.4 IO 模块
对应 io
包。
资源加载模块,主要是对类加载器进行封装,确定类加载器的使用顺序,并提供了加载类文件以及其他资源文件的功能 。
3.1.5 解析器模块
对应 parsing
包。
解析器模块,主要提供了两个功能:
- 一个功能,是对 XPath 进行封装,为 MyBatis 初始化时解析
mybatis-config.xml
配置文件以及映射配置文件提供支持。- 另一个功能,是为处理动态 SQL 语句中的占位符提供支持。
3.1.6 数据源模块
对应 datasource
包。
数据源是实际开发中常用的组件之一。现在开源的数据源都提供了比较丰富的功能,例如,连接池功能、检测连接状态等,选择性能优秀的数据源组件对于提升 ORM 框架乃至整个应用的性能都是非常重要的。
MyBatis 自身提供了相应的数据源实现,当然 MyBatis 也提供了与第三方数据源集成的接口,这些功能都位于数据源模块之中。
3.1.7 事务模块
对应 transaction
包。
MyBatis 对数据库中的事务进行了抽象,其自身提供了相应的事务接口和简单实现。
在很多场景中,MyBatis 会与 Spring 框架集成,并由 Spring 框架管理事务。
3.1.8 缓存模块
对应 cache
包。
在优化系统性能时,优化数据库性能是非常重要的一个环节,而添加缓存则是优化数据库时最有效的手段之一。正确、合理地使用缓存可以将一部分数据库请求拦截在缓存这一层。
MyBatis 中提供了一级缓存和二级缓存,而这两级缓存都是依赖于基础支持层中的缓 存模块实现的。这里需要读者注意的是,MyBatis 中自带的这两级缓存与 MyBatis 以及整个应用是运行在同一个 JVM 中的,共享同一块堆内存。如果这两级缓存中的数据量较大, 则可能影响系统中其他功能的运行,所以当需要缓存大量数据时,优先考虑使用 Redis、Memcache 等缓存产品。
3.1.9 Binding 模块
对应 binding
包。
在调用 SqlSession 相应方法执行数据库操作时,需要指定映射文件中定义的 SQL 节点,如果出现拼写错误,我们只能在运行时才能发现相应的异常。为了尽早发现这种错误,MyBatis 通过 Binding 模块,将用户自定义的 Mapper 接口与映射配置文件关联起来,系统可以通过调用自定义 Mapper 接口中的方法执行相应的 SQL 语句完成数据库操作,从而避免上述问题。
值得读者注意的是,开发人员无须编写自定义 Mapper 接口的实现,MyBatis 会自动为其创建动态代理对象。在有些场景中,自定义 Mapper 接口可以完全代替映射配置文件,但有的映射规则和 SQL 语句的定义还是写在映射配置文件中比较方便,例如动态 SQL 语句的定义。
3.1.10 注解模块
对应 annotations
包。
随着 Java 注解的慢慢流行,MyBatis 提供了注解的方式,使得我们方便的在 Mapper 接口上编写简单的数据库 SQL 操作代码,而无需像之前一样,必须编写 SQL 在 XML 格式的 Mapper 文件中。虽然说,实际场景下,大家还是喜欢在 XML 格式的 Mapper 文件中编写响应的 SQL 操作。
3.1.11 异常模块
对应 exceptions
包。
定义了 MyBatis 专有的 PersistenceException 和 TooManyResultsException 异常。
3.2 核心处理层
在核心处理层中,实现了 MyBatis 的核心处理流程,其中包括 MyBatis 的初始化以及完成一次数据库操作的涉及的全部流程 。
3.2.1 配置解析
对应 builder
和 mapping
模块。前者为配置解析过程,后者主要为 SQL 操作解析后的映射。
在 MyBatis 初始化过程中,会加载
mybatis-config.xml
配置文件、映射配置文件以及 Mapper 接口中的注解信息,解析后的配置信息会形成相应的对象并保存到 Configuration 对象中。例如:
<resultMap>
节点(即 ResultSet 的映射规则) 会被解析成 ResultMap 对象。<result>
节点(即属性映射)会被解析成 ResultMapping 对象。之后,利用该 Configuration 对象创建 SqlSessionFactory对象。待 MyBatis 初始化之后,开发人员可以通过初始化得到 SqlSessionFactory 创建 SqlSession 对象并完成数据库操作。
3.2.2 SQL 解析
对应 scripting
模块。
拼凑 SQL 语句是一件烦琐且易出错的过程,为了将开发人员从这项枯燥无趣的工作中 解脱出来,MyBatis 实现动态 SQL 语句的功能,提供了多种动态 SQL语句对应的节点。例如
<where>
节点、<if>
节点、<foreach>
节点等 。通过这些节点的组合使用, 开发人 员可以写出几乎满足所有需求的动态 SQL 语句。MyBatis 中的
scripting
模块,会根据用户传入的实参,解析映射文件中定义的动态 SQL 节点,并形成数据库可执行的 SQL 语句。之后会处理 SQL 语句中的占位符,绑定用户传入的实参。
3.2.3 SQL 执行
对应 executor
和 cursor
模块。前者对应执行器,后者对应执行结果的游标。
SQL 语句的执行涉及多个组件 ,其中比较重要的是 Executor、StatementHandler、ParameterHandler 和 ResultSetHandler 。
- Executor 主要负责维护一级缓存和二级缓存,并提供事务管理的相关操作,它会将数据库相关操作委托给 StatementHandler完成。
- StatementHandler 首先通过 ParameterHandler 完成 SQL 语句的实参绑定,然后通过
java.sql.Statement
对象执行 SQL 语句并得到结果集,最后通过 ResultSetHandler 完成结果集的映射,得到结果对象并返回。整体过程如下图:
整体过程
3.2.4 插件层
对应 plugin
模块。
Mybatis 自身的功能虽然强大,但是并不能完美切合所有的应用场景,因此 MyBatis 提供了插件接口,我们可以通过添加用户自定义插件的方式对 MyBatis 进行扩展。用户自定义插件也可以改变 Mybatis 的默认行为,例如,我们可以拦截 SQL 语句并对其进行重写。
由于用户自定义插件会影响 MyBatis 的核心行为,在使用自定义插件之前,开发人员需要了解 MyBatis 内部的原理,这样才能编写出安全、高效的插件。
3.3 接口层
对应 session
模块。
接口层相对简单,其核心是 SqlSession 接口,该接口中定义了 MyBatis 暴露给应用程序调用的 API,也就是上层应用与 MyBatis 交互的桥梁。接口层在接收到调用请求时,会调用核心处理层的相应模块来完成具体的数据库操作。
3.4 其它层
这块,严格来说,不能叫做一个层。考虑到统一,就简单这么命名把。哈哈哈。
3.4.1 JDBC 模块
对应 jdbc
包。
JDBC 单元测试工具类。所以,不感兴趣的同学,已经可以忽略 1236 行代码了。
3.4.2 Lang 模块
对应 lang
包。
看不懂具体用途,暂时误会。
3.4 总结
总的来说,MyBatis 的代码,还是比较简单易懂。并且,看着包名,基本也能猜到大体的用途。在网络上找了一个总结的图,大家瞅瞅:
FROM 《mybatis 源码分析之整体架构分析》
而接下来的内容,我也会从模块到流程开始分析
相关文章:
mybatis源码学习-2-项目结构
写在前面,这里会有很多借鉴的内容,有以下三个原因 本博客只是作为本人学习记录并用以分享,并不是专业的技术型博客笔者是位刚刚开始尝试阅读源码的人,对源码的阅读流程乃至整体架构并不熟悉,观看他人博客可以帮助我快速入门如果只是笔者自己观看,难免会有很多弄不懂乃至理解错误…...
selenium 自动化测试——环境搭建
安装python,并且使用pip命令安装 selenium pip3 install selenium 然后尝试第一次使用selenium 完成一个简单的测试自动化脚本 from selenium import webdriver from selenium.webdriver.common.by import By import timedriver webdriver.Chrome() driver.get(…...
得物一面,场景题问得有点多!
题目来源:https://www.nowcoder.com/discuss/525371909735792640 前文 本期是【捞捞面经】系列文章的第 1 期,持续更新中…。 《捞捞面经》系列正式开始连载啦,据说看了这个系列的朋友都拿到了大厂offer~ 欢迎星标订阅,持续更新…...
Prompt Tuning 和instruct tuning
Prompt Tuning 是啥? prompt的思想是,把下游任务的输入转化为预训练模型的原始任务。 以bert作为举例,假设任务是文本分类。“今天天气很好。”我们想判断一下这句话的情感是正面还是负面 fine-tune的方法是在bert之后接一个head࿰…...
springboot 与异步任务,定时任务,邮件任务
异步任务 在Java应用中,绝大多数情况下都是通过同步的方式来实现交互处理的;但是在处理与第三方系统交互的时候,容易造成响应迟缓的情况,之前大部分都是使用多线程来完成此类任务,其实,在Spring 3.x之后&a…...
2022年06月 C/C++(六级)真题解析#中国电子学会#全国青少年软件编程等级考试
C/C++编程(1~8级)全部真题・点这里 第1题:小白鼠再排队2 N只小白鼠(1 < N < 100),每只鼠头上戴着一顶有颜色的帽子。现在称出每只白鼠的重量,要求按照白鼠重量从小到大的顺序输出它们头上帽子的颜色。帽子的颜色用 “red”,“blue”等字符串来表示。不同的小白鼠可…...
【C++】C++11新特性(下)
上篇文章(C11的新特性(上))我们讲述了C11中的部分重要特性。本篇接着上篇文章进行讲解。本篇文章主要进行讲解:完美转发、新类的功能、可变参数模板、lambda 表达式、包装器。希望本篇文章会对你有所帮助。 文章目录 一…...
python内网环境安装第三方包
文章目录 一、问题二、解决方法三、代码实现 一、问题 内网安装第三方包的应用场景,一般是一些需要在没网的环境下进行开发的情况。这些环境一般仅支持本地局域网访问,所以只能在不下载任何第三方包的情况下艰难开发。 二、解决方法 将当前应用依赖的第…...
javaScipt
javaScipt 一、JavaScript简介二、javaScript基础1、输入输出语法2、变量3、常量4、数据类型4.1、数字型 number4.2、字符串类型 string4.3、布尔类型 boolean4.4、未定义类型 undefined4.5、null 空类型4.6、typeof 检测变量数据类型 5、数据类型转换5.1、隐式转换5.2、显示转…...
Linux(实操篇三)
Linux实操篇 Linux(实操篇三)1. 常用基本命令1.7 搜索查找类1.7.1 find查找文件或目录1.7.2 locate快速定位文件路径1.7.3 grep过滤查找及"|"管道符 1.8 压缩和解压类1.8.1 gzip/gunzip压缩1.8.2 zip/unzip压缩1.8.3 tar打包 1.9 磁盘查看和分区类1.9.1 du查看文件和…...
数学之美 — 1
为什么你会想和他人共享那些美丽的事物呢?因为这会让他(她)感到愉悦,也能让你在分享的过程中重新欣赏一次事物的美。 ——David Blackwell 1、感官之美,对于那些有规律的事物,你可以利用自己的视觉、触觉、…...
python中的global关键字
在Python中,global关键字用于在函数内部声明一个全局变量。默认情况下,函数内部的变量是局部变量,只能在函数内部访问。使用global关键字可以在函数内部创建或修改全局变量,使其在函数外部也可见和修改。 以下是使用global关键字…...
Matlab图像处理-幂次变换
幂次变换 如下图所示的幂次变换函数曲线图: 当γ <1时,效果和对数变换相似,放大暗处细节,压缩亮处细节,随着数值减少,效果越强。 当γ >1时,放大亮处细节,压缩暗处细节&…...
浏览器输入 URL 地址,访问主页的过程
分析&回答 浏览器解析域名;TCP建立连接;浏览器向服务器发送HTTP请求;服务器解析请求并返回HTTP报文;浏览器解析并渲染页面;断开连接。 反思&扩展 域名解析的流程 查找浏览器缓存——我们日常浏览网站时&am…...
每日一学————基本配置和管理
一、交换机的基本配置 配置enable口令、密码和主机名 Switch> (用户执行模式提示符) Switch>enable (进入特权模式) Switch# …...
解决 filezilla 连接服务器失败问题
问题描述: 开始一直用的 XFTP 后来,它变成收费软件了,所以使用filezilla 代替 XFTP 之前用的还好好的,今天突然就报错了:按要求输入相关字段,连接 连接失败!!!o(╥﹏╥…...
如何使用Java进行机器学习?
在Java中进行机器学习,可以使用各种开源机器学习库和框架来实现。以下是一些常用的Java机器学习库: Weka:Weka 是一个非常流行的机器学习库,提供了大量的算法和工具,以及用于数据预处理、特征选择和可视化的功能。 De…...
springsecurity+oauth 分布式认证授权笔记总结12
一 springsecurity实现权限认证的笔记 1.1 springsecurity的作用 springsecurity两大核心功能是认证和授权,通过usernamepasswordAuthenticationFilter进行认证;通过filtersecurityintercepter进行授权。springsecurity其实多个filter过滤链进行过滤。…...
如何在职业生涯中取得成功
工作中让你有强烈情绪波动的事情 在我的工作经历中,有一次让我经历了强烈情绪波动的事件。我曾在一个高压的项目团队中工作,我们需要在极短的时间内完成一个复杂的客户项目。这个项目的截止日期非常紧迫,而项目的规模和要求也一直在不断增加…...
Hive-安装与配置(1)
🥇🥇【大数据学习记录篇】-持续更新中~🥇🥇 个人主页:beixi 本文章收录于专栏(点击传送):【大数据学习】 💓💓持续更新中,感谢各位前辈朋友们支持…...
链表模拟栈
定义节点 class Node {var num: Int _var next: Node _def this(num: Int) {thisthis.num num}override def toString: String s"num[${this.num}]" }定义方法 class LinkStack {private var head new Node(0)def getHead: Node head//判断是否为空def isEmp…...
MySQL基础篇:数据库概述和部署
SQL 概述 SQL,一般发音为sequel,SQL的全称Structured Query Language),SQL用来和数据库打交道,完成和数据库的通信,SQL是一套标准。但是每一个数据库都有自己的特性别的数据库没有,当使用这个数据库特性相关的功能,这…...
大数据面试题:MapReduce压缩方式
面试题来源: 《大数据面试题 V4.0》 大数据面试题V3.0,523道题,679页,46w字 可回答:1)Hadoop常见的压缩算法有哪些? 问过的一些公司:网易云音乐(2022.11),阿里(2020.…...
【ICer的脚本练习】“精通各种语言的hello world!“
系列的目录说明请见:ICer的脚本练习专栏介绍与全流程目录_尼德兰的喵的博客-CSDN博客 前言 这一节呢主要是检查一下Linux和win环境是不是能正常的支持咱们的脚本学习,所以来答应各种语言的hello world!,毕竟打印了就是学会了٩(๑❛ᴗ❛๑)۶…...
解决npm install报错: No module named gyp
今天运行一个以前vue项目,启动时报错如下: ERROR Failed to compile with 1 error上午10:19:33 error in ./src/App.vue?vue&typestyle&index0&langscss& Syntax Error: Error: Missing binding D:\javacode\Springboot-MiMall-RSA\V…...
Leetcode 面试题 17.01 不用加号的加法
设计一个函数把两个数字相加。不得使用 或者其他算术运算符。 示例: 输入: a 1, b 1 输出: 2 提示: a, b 均可能是负数或 0结果不会溢出 32 位整数 我的答案: 一、信息 1.设计一个函数把两个数相加 2.不得使用或者其他运算符 3.a,b均为负数或…...
一个 MySQL 数据库死锁的案例和解决方案
本文介绍了一个 MySQL 数据库死锁的案例和解决方案。 场景 生产环境出了一个偶现的数据库死锁问题,导致少部分业务处理失败。 分析特征之后,发现是多个线程并发执行同一个方法,更新关联的数据时可能会出现,把场景简化概括一下&…...
AMBEO 双声道空间音频现已迈进直播制作领域
图片来源:Unsplash,作者:Bence Balla-Schottner AMBEO 双声道空间音频现已迈进直播制作领域 为所有观众解锁更加身临其境的听觉体验 森海塞尔将功能强大的 AMBEO 双声道空间音频技术引入了广播电视直播应用领域,对所有体育赛事广…...
在VSCode上画UML的三个插件
2023年9月2日,周六晚上 因为写代理模式的博客时需要画UML,所以就在网上找了半天, 最后觉得VSCode上的这三个插件比较好用 目录 三个画UML的VSCode插件PlantUMLDraw.io IntegrationUMLet我个人推荐使用PlantUML 三个画UML的VSCode插件 Pla…...
Springboot - 1.什么是springboot
👀Spring的核心模块 Spring Framework是一个功能强大的开源框架,用于构建Java企业级应用程序。它提供了多个核心模块,每个模块都提供不同的功能,用于解决应用程序开发中的各种问题。以下是Spring Framework的核心模块的全面解析&…...
南京专业做网站的公司/百度提交工具
原文地址为: IE6和IE7共存方法(别人是别人的,我是我的)2009年9月3日更新 本文是较老的文章,最新的共存方法,建议使用IETester最新版。最近版IETester的下载和介绍,请阅读文章《IETester更新至v0…...
java做网站教程/怎么做百度搜索排名
在ArcGIS中使用镶嵌数据集,你为它构建过“概视图”,也就是overview吗?你有过疑问,这个概视图和影像金字塔是什么关系?对于单景影像(栅格数据集),为了加快影像显示速度,我…...
简单的企业网站php/西安网站搭建公司
set和multiset会根据特定的排序准则,自动将元素排序。两者不同处在于multiset允许元素重复而set不允许。 一、集和多集(set 和multiset 容器类) 在使用set和multiset之前,先必须包含头文件<set>#include <set>在其中&…...
网站开发的后台技术/商丘优化公司
scratch3.0中我们通过添加“朗读文字”扩展便可以编写程序,将文字朗读出来。那么如何编程,让Python将文字转成语音并读出来?方法比较多,我们在此先介绍一种(利用系统内置语音引擎实现发音),其他方法大家可以网上找到答…...
java 做直播网站有哪些软件有哪些/seminar怎么读
一、 资源准备 1) 将U盘中的py文件拷贝到要安装环境的电脑上,文件中内容如下图1所示: 2) 在C:\Users\Administrator\AppData\Roaming\pip目录下新建pip文件夹,如下图所示: 3) 将py文件中的pip文件拷贝至2…...
呼和浩特企业网站/公众号营销
我们在之前就讨论了为什么在高并发的情况下,程序会崩溃。主要原因是,在高并发的情况下,有大量用户请求需要程序计算处理,而目前的处理方式是,为每个用户请求分配一个线程,当程序内部因为访问数据库等原因造…...