MyBatis源码用了哪些设计模式?

news2024/11/28 10:50:54

MyBatis源码用了哪些设计模式?

  • 前言
  • 一、创建型模式
    • 工厂模式
    • 单例模式
    • 建造者模式
  • 二、结构型模式
    • 适配器模式
    • 代理模式
    • 组合模式
    • 装饰器模式
  • 三、行为型模式
    • 模板模式
    • 策略模式
    • 迭代器模式
  • 总结

前言

在 MyBatis 的两万多行的框架源码中,使用了大量的设计模式对工程架构中的复杂场景进行解耦,这些设计模式的巧妙使用是整个框架的精华。
在这里插入图片描述

一、创建型模式

工厂模式

工厂模式:简单工厂是一种创建型模式,在父类中提供一个创建对象的方法,允许子类决定实例对象的类型。

SqlSessionFactory 的结构如图所示。

在这里插入图片描述

场景介绍:SqlSessionFactory 是获取会话的工厂,每次使用MyBatis 操作数据库时, 都会开启一个新的会话。在会话工厂的实现中,SqlSessionFactory 负责获取数据源环境配置信息、构建事务工厂和创建操作SQL 的执行器,最终返回会话实现类。

同类设计:

  • SqlSessionFactory
  • ObjectFactory
  • MapperProxyFactory
  • DataSourceFactory

单例模式

Configuration 单例配置类的结构如图所示。
在这里插入图片描述
单例模式:是一种创建型模式,能够保证一个类只有一个实例,并且提供一个访问该实例的全局节点。

场景介绍:Configuration 是一个大单例,贯穿整个会话周期,所有的配置对象(如映射、缓存、入参、出参、拦截器、注册机和对象工厂等)都在Configuration 配置项中初始化, 并且随着SqlSessionFactoryBuilder 构建阶段完成实例化操作。

同类场景:

  • ErrorContext
  • LogFactory
  • Configuration

建造者模式

ResultMap 建造者模式的结构如图所示。
在这里插入图片描述
建造者模式:使用多个简单的对象一步一步地构建成一个复杂的对象,提供了一种创建对象的最佳方式。

场景介绍:建造者模式在MyBatis 中使用了大量的XxxxBuilder,将XML 文件解析到各类对象的封装中,使用建造者及建造者助手完成对象的封装。它的核心目的是不希望把过多的关于对象的属性设置写到其他业务流程中,而是用建造者方式提供最佳的边界隔离。

同类场景:

  • SqlSessionFactoryBuilder
  • XMLConfigBuilder
  • XMLMapperBuilder
  • XMLStatementBuilder
  • CacheBuilder

二、结构型模式

适配器模式

日志实现类的结构如图所示。
在这里插入图片描述
适配器模式:是一种结构型模式,能使接口不兼容的对象也可以相互合作。

场景介绍:正是因为有太多的日志框架,包括Log4j、Log4j2 和Slf4J 等,而这些日志框架的使用接口又各有差异,为了统一这些日志框架的接口,MyBatis 定义了一套统一的接口,为所有的其他日志框架的接口做相应的适配。

同类场景:主要集中在对Log 日志的适配上。

代理模式

代理模式的实现结构如图所示。
在这里插入图片描述
代理模式:是一种结构型模式,能够提供对象的替代品或占位符。代理控制元对象的访问,并且允许在将请求提交给对象前进行一些处理。

场景介绍:没有代理模式就不存在各类框架。就像MyBatis 中的MapperProxy 实现类, 代理工厂实现的功能就是完成DAO 接口的具体实现类的方法,配置的任何一个DAO 接口调用的CRUD 方法,都会被MapperProxy 接管,调用到方法执行器等,并返回最终的数据库执行结果。

同类场景:

  • DriverProxy
  • Plugin
  • Invoker
  • MapperProxy

组合模式

解析节点类的结构如图所示。
在这里插入图片描述
组合模式:是一种结构型模式,可以将对象组合成树形结构以表示“部分—整体” 的层次结构。

场景介绍:在MyBatis XML 动态的SQL 配置中,共提供了9 种标签(trim、where、set、foreach、if、choose、when、otherwise 和bind),使用者可以组合出各类场景的SQL 语句。而SqlNode 接口的实现就是每个组合结构中的规则节点,通过规则节点的组装,完成规则树组合模式的使用。

同类场景:主要体现在对各类SQL 标签的解析上,以实现SqlNode 接口的各个子类为主。

装饰器模式

二级缓存装饰器的实现结构如图所示。
在这里插入图片描述
装饰器模式:是一种结构型设计模式,允许将对象放入包含行为的特殊封装对象中, 为元对象绑定新的行为。

场景介绍:MyBatis 的所有SQL 操作都是经过SqlSession 调用SimpleExecutor 完成的, 而一级缓存的操作也是在简单执行器中处理的。这里的二级缓存因为是基于一级缓存刷新的,所以在实现上,通过创建一个缓存执行器,包装简单执行器的处理逻辑,实现二级缓存操作。这里用到的就是装饰器模式,也叫俄罗斯套娃模式。

三、行为型模式

模板模式

SQL 执行模板模式如图所示。
在这里插入图片描述
模板模式:是一种行为型模式,在超类中定义了一个算法的框架,允许子类在不修改结构的情况下重写算法的特定步骤。场景介绍:存在一系列可被标准定义的流程,并且流程的步骤大部分采用通用逻辑,只有一小部分是需要子类实现的,通常采用模板模式来定义这个标准的流程。就像MyBatis 的BaseExecutor 就是一个用于定义模板模式的抽象类,在这个类中把查询、修改的操作都定义为一套标准的流程。

同类场景:

  • BaseExecutor
  • SimpleExecutor
  • BaseTypeHandler

策略模式

多类型处理器策略模式的结构如图所示。

在这里插入图片描述
策略模式:是一种行为型模式,能定义一系列算法,并将每种算法分别放入独立的类中,从而使算法的对象能够互相替换。

场景介绍:在MyBatis 处理JDBC 执行后返回的结果时,需要按照不同的类型获取对应的值,这样就可以避免大量的if 判断。所以,这里基于TypeHandler 接口对每个参数类型分别做了自己的策略实现。

同类场景:

  • PooledDataSource
  • UnpooledDataSource
  • BatchExecutor
  • ResuseExecutor
  • SimpleExector
  • CachingExecutor
  • LongTypeHandler
  • StringTypeHandler
  • DateTypeHandler

迭代器模式

拆解字段解析实现的结构如图所示。
在这里插入图片描述
迭代器模式:是一种行为模式,能在不暴露集合底层表现形式的情况下遍历集合中的所有元素。

场景介绍:PropertyTokenizer 用于MyBatis 的MetaObject 反射工具包下,用来解析对象关系的迭代操作。这个类在MyBatis 中使用得非常频繁,包括解析数据源配置信息并填充到数据源类上,同时参数的解析、对象的设置都会使用这个类。

同类场景:PropertyTokenizer。

总结

通过梳理,MyBatis大约运用了10种左右设计模式。可以说,复杂且优秀的ORM 框架源码在设计和实现的过程中都会使用大量的设计模式。

在解决复杂场景的问题时,需要采用分治、抽象的方法,运用设计模式和设计原则等相关知识,把问题合理切割为若干子问题,以便加以理解和解决。

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

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

相关文章

Oracle OCP 19c 考试(1Z0-083)中关于Oracle不完全恢复的考点(文末附录像)

欢迎试看博主的专著《MySQL 8.0运维与优化》 下面是Oracle 19c OCP考试(1Z0-083)中关于Oracle不完全恢复的题目: A database is configured in ARCHIVELOG mode A full RMAN backup exists but no control file backup to trace has been taken A media…

Spatial-Temporal Graph ODE Networks for Traffic Flow Forecasting

Spatial-Temporal Graph ODE Networks for Traffic Flow Forecasting 摘要 交通流量的复杂性和长范围时空相关性是难点 经典现存的工作: 1.利用浅图神经网络(shallow graph convolution networks)和 时间提取模块去分别建模空间和时间依赖…

【Python3安装部署的保姆级教程】

如何在Windows 10上安装Python Python是一种越来越受欢迎的编程语言,无论是对于初学者还是有经验的开发者。Python灵活多用,擅长脚本、自动化、数据分析、机器学习和后端开发。在本教程中,你将学习如何使用Windows的Python安装程序在Windows 10上安装Python。 第一步 — 下…

Python3-错误和异常

Python3 错误和异常 作为 Python 初学者,在刚学习 Python 编程时,经常会看到一些报错信息,在前面我们没有提及,这章节我们会专门介绍。 Python 有两种错误很容易辨认:语法错误和异常。 Python assert(断…

进程间通信IPC

进程间通信IPC (InterProcess Communication) 一、进程间通信的概念 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程1把数据…

MySQL事务详解与隔离级别的实现

文章目录一、四个特性二、存在问题三、隔离级别四、实现原理0、SQL语句执行流程1)buffer pool2)执行流程1、日志1)binlog2)redolog3)对比4)undolog2、MVCC原理1)隐式字段2)undo log版…

气泡式水位计的安装方法详解

气泡水位计的安装实际上就是气管的安装,气管的安装是否正确将直接影响到仪器测量数据的结果,气泡水位计它由活塞泵产生的压缩空气流经测量管和气泡室,进入被测的水体中,测量管中的静压力与气泡室上的水位高度成正比。那么接下来就…

蓝桥杯集训·每日一题Week1

前缀和(Monday) AcWing 3956. 截断数组(每日一题) 思路: 首先可以预处理出前缀和。判断数组长度如果小于 333 或者前 nnn 项不是 333 的倍数,则可以直接输出 000。 否则就枚举所有 s[i]s[n]3s[i] \cfrac…

kali双网卡

先单独开启一个网卡,配置/etc/network/interfaces 修改为如下配置 This file describes the network interfaces available on your system and how to activate them. For more information, see interfaces(5). source /etc/network/interfaces.d/* The loopb…

JVM系列——Java与线程,介绍线程原理和操作系统的关系

并发不一定要依赖多线程(如PHP中很常见的多进程并发)。 但是在Java里面谈论并发,基本上都与线程脱不开关系。因此我们讲一下从Java线程在虚拟机中的实现。 线程的实现 线程是比进程更轻量级的调度执行单位。 线程的引入,可以把一个进程的资源分配和执行调…

【深度强化学习】(3) Policy Gradients 模型解析,附Pytorch完整代码

大家好,今天和各位分享一下基于策略的深度强化学习方法,策略梯度法是对策略进行建模,然后通过梯度上升更新策略网络的参数。我们使用了 OpenAI 的 gym 库,基于策略梯度法完成了一个小游戏。完整代码可以从我的 GitHub 中获得&…

原型模式(设计模式详解)

原型模式 描述 原型模式(Prototype Pattern)是一种创建型设计模式,它允许通过复制现有对象来创建新对象,而无需从头开始编写代码。 在原型模式中,一个原型对象作为模板,新的对象通过克隆这个原型对象而创…

MySQL OCP888题解048-letter N in slow query log(慢查询日志里的字母N)

文章目录1、原题1.1、英文原题1.2、中文翻译1.3、答案2、题目解析2.1、题干解析2.2、选项解析3、知识点3.1、知识点1:mysqldumpslow - 总结缓慢的查询日志文件4、实验4.1、实验14.1.1、实验目的4.1.2、实验前准备4.1.3、实验步骤4.1.4、实验结论5、总结1、原题 1.1…

dva01-初识

背景 React 本身只是一个 DOM 的抽象层,使用组件构建虚拟 DOM。如果开发大应用,还需要解决一个问题。 通信:React 只提供了一种传参手段,后续数据变化非常麻烦,无法适用于大应用。数据流:每次要更新数据&…

ACE C++网络通信框架深入解析ACE_Message_Block消息类

前言 我所见到最好消息包的接口设计莫过于ACE_Message_Block了。 为什么这样说呢? 对于它的API说明,我最初仅想在它的基础上提供注释说明,而不想多言其它,因为无需多言其他。 不过,后来还是补充两个图,以…

后台搭建常用方式及常用的插件

利用脚手架创建项目 create-vite 是一个快速生成主流框架基础模板的工具,安装后启动预设创建项目 使用NPM: npm create vitelatest 使用Yarn: yarn create vite 使用PNPM: pnpm create vite 开始 | Vite 官方中文文档 create-vue,是 Vue 官方的项目脚…

Flume工作原理 安装配置

目录 简介 主要功能 日志收集 数据处理 工作原理 Flume架构 安装 拷贝压缩包 解压 改名 修改配置文件 安装nc(netcat) 安装telnet协议 应用 应用一:实时监听 新建netcat-logger.conf文件 开启端口监听方式一 访问主机 开启…

flume安装与配置

目录 flume描述 flume用途 flume基本组件 配置flume 搭建环境: 解压flume安装包将其放入到opt/soft目录 在/opt/soft目录下将apache-flume-1.9.0-bin.tar.gz 改名为flume190 到/opt/soft/flume190/conf目录中将临时配置文件flume-env.sh.template拷贝为配置文…

香港酒店模拟分析项目报告--使用tableau、python、matlab

转载请标记本文出处 软件:tableau、pycharm、关系型数据库:MySQL 数据大量分析考虑电脑性能的情况。 文章目录前言一、爬虫是什么?二、使用tableau数据可视化1.引入数据1.1 制作直方图-各地区酒店数量条形图1.2 各地区酒店均价1.3 价格等级堆…

Idea+maven+spring-cloud项目搭建系列--11-3 dubbo限流和熔断

前言: dubbo 作为rpc 通信组件,在使用过程中,如何避免服务提供端被多个消费端撑爆,消费端如何避免因为服务端的故障造成结果响应超时。 1 服务提供端的限流措施: 1.1 使用 :dubbo.protocol.accepts 参数限制服务端同…