MyBatis 架构分析

文章目录

  • 三层架构
    • 一、基础支撑层
      • 1.1 类型转换模块
      • 1.2 日志模块
      • 1.3 反射工具模块
      • 1.4 Binding 模块
      • 1.5 数据源模块
      • 1.6 缓存模块
      • 1.6 解析器模块
      • 1.7 事务管理模块
    • 二、核心处理层
      • 2.1 配置解析
      • 2.2 SQL 解析与 scripting 模块。
      • 2.3 MyBatis 中的 scripting 模块就是负责动态生成 SQL 的核心模块。
      • 2.4 SQL 执行
      • 2.5 插件
    • 三、接口层

三层架构

MyBatis 分为三层架构,分别是基础支撑层、核心处理层和接口层

在这里插入图片描述

一、基础支撑层

基础支撑层是整个 MyBatis 框架的地基,为整个 MyBatis 框架提供了非常基础的功能,其中每个模块都提供了一个内聚的、单一的能力,MyBatis 基础支撑层按照这些单一的能力可以划分为上图所示的九个基础模块。

由于资源加载模块的功能非常简单,使用频率也不高,这里我就不介绍了,你若感兴趣可以自行查阅相关资料去了解和学习。下面我就来简单描述这剩下的八个模块的基本功能,在本课程第二个模块,我还会带你详细分析这些基础模块的具体实现。

1.1 类型转换模块

在上一讲展示的订单系统实现中,我们可以在 mybatis-config.xml 配置文件中通过 标签为一个类定义一个别名,这里用到的“别名机制”就是由 MyBatis 基础支撑层中的类型转换模块实现的。

除了“别名机制”,类型转换模块还实现了 MyBatis 中 JDBC 类型与 Java 类型之间的相互转换,这一功能在绑定实参、映射 ResultSet 场景中都有所体现:

在 SQL 模板绑定用户传入实参的场景中,类型转换模块会将 Java 类型数据转换成 JDBC 类型数据;
在将 ResultSet 映射成结果对象的时候,类型转换模块会将 JDBC 类型数据转换成 Java 类型数据。
在这里插入图片描述

1.2 日志模块

日志是我们生产实践中排查问题、定位 Bug、锁定性能瓶颈的主要线索来源,在任何一个成熟系统中都会有级别合理、信息翔实的日志模块,MyBatis 也不例外。MyBatis 提供了日志模块来集成 Java 生态中的第三方日志框架,该模块目前可以集成 Log4j、Log4j2、slf4j 等优秀的日志框架。

1.3 反射工具模块

Java 中的反射功能非常强大,许多开源框架都会依赖反射实现一些相对灵活的需求,但是大多数 Java 程序员在实际工作中很少会直接使用到反射技术。MyBatis 的反射工具箱是在 Java 反射的基础之上进行的一层封装,为上层使用方提供更加灵活、方便的 API 接口,同时缓存 Java 的原生反射相关的元数据,提升了反射代码执行的效率,优化了反射操作的性能

1.4 Binding 模块

在上一讲介绍的订单系统示例中,我们可以通过 SqlSession 获取 Mapper 接口的代理,然后通过这个代理执行关联 Mapper.xml 文件中的数据库操作。通过这种方式,可以将一些错误提前到编译期,该功能就是通过 Binding 模块完成的。

这里特别说明的是,在使用 MyBatis 的时候,我们无须编写 Mapper 接口的具体实现,而是利用 Binding 模块自动生成 Mapper 接口的动态代理对象。有些简单的数据操作,我们还可以直接在 Mapper 接口中使用注解完成,连 Mapper.xml 配置文件都无须编写,但如果 ResultSet 映射以及动态 SQL 非常复杂,还是建议在 Mapper.xml 配置文件中维护会比较方便。

1.5 数据源模块

持久层框架核心组件之一就是数据源,一款性能出众的数据源可以成倍提升系统的性能。MyBatis 自身提供了一套不错的数据源实现,也是 MyBatis 的默认实现。另外,在 Java 生态中,就有很多优异开源的数据源可供选择,MyBatis 的数据源模块中也提供了与第三方数据源集成的相关接口,这也为用户提供了更多的选择空间,提升了数据源切换的灵活性。

1.6 缓存模块

数据库是实践生成中非常核心的存储,很多业务数据都会落地到数据库,所以数据库性能的优劣直接影响了上层业务系统的优劣。我们很多线上业务都是读多写少的场景,在数据库遇到瓶颈时,缓存是最有效、最常用的手段之一(如下图所示),正确使用缓存可以将一部分数据库请求拦截在缓存这一层,这就能够减少一部分数据库的压力,提高系统性能。

在这里插入图片描述
除了使用 Redis、Memcached 等外置的第三方缓存以外,持久化框架一般也会自带内置的缓存,例如,MyBatis 就提供了一级缓存和二级缓存,具体实现位于基础支撑层的缓存模块中。

1.6 解析器模块

在上一讲的订单系统示例中,我们可以看到 MyBatis 中有两大部分配置文件需要解析,一个是 mybatis-config.xml 配置文件,另一个是 Mapper.xml 配置文件。这两个文件都是由 MyBatis 的解析器模块进行解析的,其中主要是依赖 XPath 实现 XML 配置文件以及各类表达式的高效解析。

1.7 事务管理模块

持久层框架一般都会提供一套事务管理机制实现数据库的事务控制,MyBatis 对数据库中的事务进行了一层简单的抽象,提供了简单易用的事务接口和实现。一般情况下,Java 项目都会集成 Spring,并由 Spring 框架管理事务。在后面的课程中,我还会深入讲解 MyBatis 与 Spring 集成的原理,其中就包括事务管理相关的集成。

二、核心处理层

介绍完 MyBatis 的基础支撑层之后,我们再来分析 MyBatis 的核心处理层。

核心处理层是 MyBatis 核心实现所在,其中涉及 MyBatis 的初始化以及执行一条 SQL 语句的全流程。下面我就针对核心处理层中的各部分实现进行介绍。

2.1 配置解析

我们知道,MyBatis 有三处可以添加配置信息的地方,分别是:mybatis-config.xml 配置文件、Mapper.xml 配置文件以及 Mapper 接口中的注解信息。在 MyBatis 初始化过程中,会加载这些配置信息,并将解析之后得到的配置对象保存到 Configuration 对象中。

例如,在订单系统示例中使用的 标签(也就是自定义的查询结果集映射规则)会被解析成 ResultMap 对象。我们可以利用得到的 Configuration 对象创建 SqlSessionFactory 对象(也就是创建 SqlSession 对象的工厂对象),之后即可创建 SqlSession 对象执行数据库操作了。

2.2 SQL 解析与 scripting 模块。

MyBatis 的最大亮点应该要数其动态 SQL 功能了,只需要通过 MyBatis 提供的标签即可根据实际的运行条件动态生成实际执行的 SQL 语句。MyBatis 提供的动态 SQL 标签非常丰富,包括 <where> 标签、<if> 标签、<foreach> 标签、<set> 标签等

2.3 MyBatis 中的 scripting 模块就是负责动态生成 SQL 的核心模块。

它会根据运行时用户传入的实参,解析动态 SQL 中的标签,并形成 SQL 模板,然后处理 SQL 模板中的占位符,用运行时的实参填充占位符,得到数据库真正可执行的 SQL 语句。

2.4 SQL 执行

在 MyBatis 中,要执行一条 SQL 语句,会涉及非常多的组件,比较核心的有:Executor、StatementHandler、ParameterHandler 和 ResultSetHandler。

其中,Executor 会调用事务管理模块实现事务的相关控制,同时会通过缓存模块管理一级缓存和二级缓存。SQL 语句的真正执行将会由 StatementHandler 实现。那具体是怎么完成的呢?StatementHandler 会先依赖 ParameterHandler 进行 SQL 模板的实参绑定,然后由 java.sql.Statement 对象将 SQL 语句以及绑定好的实参传到数据库执行,从数据库中拿到 ResultSet,最后,由 ResultSetHandler 将 ResultSet 映射成 Java 对象返回给调用方,这就是 SQL 执行模块的核心。

下图展示了 MyBatis 执行一条 SQL 语句的核心过程:
在这里插入图片描述
执行 SQL 语句的核心流程图

2.5 插件

很多成熟的开源框架,都会以各种方式提供扩展能力。当框架原生能力不能满足某些场景的时候,就可以针对这些场景实现一些插件来满足需求,这样的框架才能有足够的生命力。这也是 MyBatis 插件接口存在的意义。

与此同时,在实际应用的时候,你也可以通过自定义插件来扩展 MyBatis,或者改变 MyBatis 的默认行为。因为插件会影响 MyBatis 内核的行为,所以在自定义插件之前,你必须非常了解 MyBatis 内部的运行原理,以避免写出不符合预期的插件,引入一些诡异的功能 Bug 或性能问题。

三、接口层

接口层是 MyBatis 暴露给调用的接口集合,这些接口都是使用 MyBatis 时最常用的一些接口,例如,SqlSession 接口、SqlSessionFactory 接口等。其中,最核心的是 SqlSession 接口,你可以通过它实现很多功能,例如,获取 Mapper 代理、执行 SQL 语句、控制事务开关等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/240243.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringCloud Alibaba(itheima)

SpringCloud Alibaba 第一章 微服务介绍1.1系统架构演变1.1.1单体应用架构1.1.2垂直应用架构1.1.3分布式架构1.1.4 SOA架构1.1.5微服务架构 1.2微服务架构介绍1.2.1微服务架构的常见问题1.2.2微服务架构的常见概念1.2.3微服务架构的常见解决方案 1.3 SpringCloud Alibaba介绍1.…

用23种设计模式打造一个cocos creator的游戏框架----(二十二)原型模式

1、模式标准 模式名称&#xff1a;原型模式 模式分类&#xff1a;创建型 模式意图&#xff1a;用原型实例指定创建对象的种类&#xff0c;并且通过复制这些原型创建新的对象 结构图&#xff1a; 适用于&#xff1a; 1、当一个系统应该独立于它的产品创建、构成和表示时 2、…

BUUCTF-Crypto合集-WP

获取CTF工具可关注CSJH网络安全团队&#xff0c;回复CTF工具 一眼就解密 下面的字符串解密后便能获得flag&#xff1a;ZmxhZ3tUSEVfRkxBR19PRl9USElTX1NUUklOR30 注意&#xff1a;得到的 flag 请包上 flag{} 提交 大小写字母加数字&#xff0c;而且等于号结尾&#xff0c;bas…

实在智能斩获钛媒体2023全球创新评选科技类「 大模型创新应用奖」

近日&#xff0c;历时三天的钛媒体2023 T-EDGE全球创新大会以“新视野新链接”为主题在北京隆重举办。作为科创领域全新高度的年度盛事&#xff0c;大会吸引了AI各产业链近百位海内外创投人、尖端企业家、商业领袖和国际嘉宾齐聚一堂&#xff0c;围绕新一轮AI革命、智慧数字化、…

Java中使用JTS实现WKB数据写入、转换字符串、读取

场景 Java中使用JTS实现WKT字符串读取转换线、查找LineString的list中距离最近的线、LineString做缓冲区扩展并计算点在缓冲区内的方位角&#xff1a; Java中使用JTS实现WKT字符串读取转换线、查找LineString的list中距离最近的线、LineString做缓冲区扩展并计算点在缓冲区内…

从Maven初级到高级

一.Maven简介 Maven 是 Apache 软件基金会组织维护的一款专门为 Java 项目提供构建和依赖管理支持的工具。 一个 Maven 工程有约定的目录结构&#xff0c;约定的目录结构对于 Maven 实现自动化构建而言是必不可少的一环&#xff0c;就拿自动编译来说&#xff0c;Maven 必须 能…

python调用DALL·E绘画

实现用gpt的api和他对话后&#xff0c;我们试着调用DALLE的api进行绘画 参考文档 OpenAI API 运行代码 from openai import OpenAIclient OpenAI()user_prompt input("请输入您想生成的图片描述: ")response client.images.generate(model"dall-e-3"…

分享70个Java源码总有一个是你想要的

分享70个Java源码总有一个是你想要的 学习知识费力气&#xff0c;收集整理更不易。 知识付费甚欢喜&#xff0c;为咱码农谋福利。 源码下载链接&#xff1a;https://pan.baidu.com/s/1uyWfeUuO_4jRbAEw825qRw?pwd6666 提取码&#xff1a;6666 项目名称 CRUD is ReallyU…

电商数据之巅:挖掘无限价值的蓝海

在数字时代的大潮中&#xff0c;数据已成为新的黄金和石油&#xff0c;尤其在电商领域。电商平台每天都在产生海量的数据&#xff0c;这些数据不仅是对消费者行为的记录&#xff0c;更是隐藏着无限的商机和价值。本文将带你走进电商数据的神奇世界&#xff0c;探寻其无尽可能的…

Go 泛型发展史与基本介绍

Go 泛型发展史与基本介绍 Go 1.18版本增加了对泛型的支持&#xff0c;泛型也是自 Go 语言开源以来所做的最大改变。 文章目录 Go 泛型发展史与基本介绍一、为什么要加入泛型&#xff1f;二、什么是泛型三、泛型的来源四、为什么需要泛型五、Go 泛型设计的简史六、泛型语法6.1 …

实战篇:一文讲清楚商品分析之返货品画像分析怎么做

01 什么是商品画像&#xff0c;怎样进行分析 “用户画像对于小伙伴们来说并不陌生&#xff0c;那有小伙伴知道商品画像吗&#xff1f;其实它和用户画像一样&#xff0c;可以简单理解成是商品海量数据的标签。”   商品画像的意义在于可以对商品进行精准的定位&#xff0c;让不…

探索人工智能 | 计算机视觉 让计算机打开新灵之窗

前言 计算机视觉是一门研究如何使机器“看”的科学&#xff0c;更进一步的说&#xff0c;就是指用摄影机和电脑代替人眼对目标进行识别、跟踪和测量等机器视觉&#xff0c;并进一步做图形处理&#xff0c;使电脑处理成为更适合人眼观察或传送给仪器检测的图像。 文章目录 前言…

重生奇迹mu翅膀合成

在重生奇迹mu中&#xff0c;合成翅膀需要准备好翅膀碎片、宝石、羽毛、强化精华等材料&#xff0c;而其中不同翅膀合成要求的材料和数量略有不同。以下是一般合成翅膀的步骤&#xff1a; 1.首先&#xff0c;需要在背包中准备好所有的合成材料。如果缺少任何一种材料&#xff0…

Node.js安装部署

Node.js安装部署 在 Windows 上安装 Node.js1.使用安装程序2.使用包管理器 Chocolatey 安装 在 macOS 上安装 Node.js1.使用 Homebrew 安装 在 Linux 上安装 Node.js1.使用包管理器安装2.使用 Node.js 官方二进制包 安装完成验证 Node.js 是一个基于 Chrome V8 引擎的 JavaScri…

实验一传统的结构化的软件工程方法、实验二面向对象的软件工程、实验三软件测试

背景&#xff1a; 实验一 传统的结构化的软件工程方法 1实验目的 了解传统的软件工程方法的基本原理&#xff0c;掌握软件生命周期的全过程依次划分为需求分析、总体设计、详细设计、编码、测试、维护等几个重要阶段。每个阶段所要完成的任务以及提交的文档。 2实验内容 …

【LeetCode:2828. 判别首字母缩略词 | 模拟遍历】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

腾讯云服务器root登录(轻量应用服务器)

Ubuntu 系统如何使用 root 用户登录实例&#xff1f; Ubuntu 系统的默认用户名是 ubuntu&#xff0c;并在安装过程中默认不设置 root 账户和密码。您如有需要&#xff0c;可在设置中开启允许 root 用户登录。具体操作步骤如下&#xff1a; 1. 使用 ubuntu 账户登录轻量应用服…

基于Java+SpringBoot+vue+element疫情物资捐赠分配系统设计和实现

基于JavaSpringBootvueelement疫情物资捐赠分配系统设计和实现 &#x1f345; 作者主页 系统定制开发 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; 文章目录 基于JavaSpringBootvueelement疫情物资捐赠…

Blazor 混合开发_MAUI+Vue_WPF+Vue

MAUI&#xff0b;Vue 混合开发 背景混合开发的核心为什么必须使用 wwwroot 文件夹放置 Web 项目文件 创建 MAUI 项目创建 wwwroot 文件夹服务注册创建 _import.razor添加 Main.razor 组件修改 MainPage.xaml 文件 创建 WPF 项目创建 wwwroot 文件夹服务注册创建 _import.razor添…

【算法设计与分析】——动态规划算法

&#x1f383;个人专栏&#xff1a; &#x1f42c; 算法设计与分析&#xff1a;算法设计与分析_IT闫的博客-CSDN博客 &#x1f433;Java基础&#xff1a;Java基础_IT闫的博客-CSDN博客 &#x1f40b;c语言&#xff1a;c语言_IT闫的博客-CSDN博客 &#x1f41f;MySQL&#xff1a…