当前位置: 首页 > news >正文

Mybatis框架之建造者模式 (Builder Pattern)

MyBatis 框架中大量使用了 建造者模式 (Builder Pattern) 来构建复杂的对象,尤其是在 SQL 语句的解析、配置对象的创建以及动态 SQL 的生成 等方面。建造者模式使得 MyBatis 能够更灵活、清晰地构建对象,尤其是那些需要多步创建和配置的复杂对象。

1. 什么是建造者模式 (Builder Pattern)?

建造者模式 是一种创建型设计模式,用于将一个复杂对象的构建与其表示分离,使得同样的构建过程可以创建不同的表示。

特点
  • 分步构建:将对象的构建过程分为多个步骤,每一步负责配置对象的某一部分。
  • 解耦构建和表示:建造者模式将对象的构建过程与对象的表示分离,使得我们可以通过不同的建造者创建不同的对象表示。
  • 易于扩展:通过定义新的建造者类,可以轻松扩展对象的创建方式。

2. MyBatis 中建造者模式的应用场景

在 MyBatis 中,建造者模式被广泛应用于以下几个场景:

  • SqlSessionFactoryBuilder:用于创建 SqlSessionFactory 对象。
  • XMLConfigBuilderXMLMapperBuilder:用于解析 XML 配置文件和映射文件。
  • 动态 SQL 语句构建:通过 SQL 类来动态生成 SQL 语句。

3. MyBatis 建造者模式的实现

3.1 SqlSessionFactoryBuilder

SqlSessionFactoryBuilder 是 MyBatis 中最典型的建造者模式的实现,它用于构建 SqlSessionFactory 对象。SqlSessionFactory 是 MyBatis 的核心接口,用于创建 SqlSession,而 SqlSession 则是用于执行 SQL 语句、获取 Mapper 实例的接口。

构建流程
  1. 加载 MyBatis 配置文件。
  2. 解析配置文件,构建 Configuration 对象。
  3. 使用 Configuration 对象创建 SqlSessionFactory 实例。
代码示例
Step 1: 使用 SqlSessionFactoryBuilder 创建 SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
Step 2: 解析配置文件 (SqlSessionFactoryBuilder 源码示例)
public class SqlSessionFactoryBuilder {public SqlSessionFactory build(InputStream inputStream) {// 1. 创建 XML 配置解析器XMLConfigBuilder parser = new XMLConfigBuilder(inputStream);// 2. 解析配置文件并构建 Configuration 对象Configuration configuration = parser.parse();// 3. 使用 Configuration 对象创建 SqlSessionFactoryreturn new DefaultSqlSessionFactory(configuration);}
}
Step 3: 解析 XML 配置文件 (XMLConfigBuilder 源码示例)
public class XMLConfigBuilder {private Configuration configuration;public XMLConfigBuilder(InputStream inputStream) {this.configuration = new Configuration();this.parser = new XPathParser(inputStream);}public Configuration parse() {// 解析 <environments>、<mappers> 等标签parseConfiguration(parser.evalNode("/configuration"));return configuration;}private void parseConfiguration(XNode root) {// 解析不同的配置节点environmentsElement(root.evalNode("environments"));mappersElement(root.evalNode("mappers"));}
}

4. MyBatis 中的动态 SQL 构建

MyBatis 还使用建造者模式来构建动态 SQL 语句。通过 SQL 提供一种灵活的方式来动态构建复杂的 SQL 语句。

示例代码
import org.apache.ibatis.jdbc.SQL;public String buildSelectUserSql() {return new SQL().SELECT("id, name, email").FROM("users").WHERE("status = 'active'").ORDER_BY("created_at DESC").toString();
}

生成的 SQL 语句为:

SELECT id, name, email FROM users WHERE status = 'active' ORDER BY created_at DESC;
解析
  • SQL 类是 MyBatis 提供的一个内置的建造者工具,用于动态拼接 SQL 语句。
  • 每个方法(如 SELECT()FROM()WHERE() 等)都会返回当前对象 (this),从而支持链式调用。

5. MyBatis 中 MapperBuilderAssistant

MyBatis 还使用了 MapperBuilderAssistant 类来帮助构建 Mapper 的映射配置。

代码片段示例
public class XMLMapperBuilder {private final MapperBuilderAssistant builderAssistant;public XMLMapperBuilder(InputStream inputStream, Configuration configuration, String resource) {this.builderAssistant = new MapperBuilderAssistant(configuration, resource);}public void parse() {// 解析 SQL 语句builderAssistant.addMappedStatement(id, sqlSource, ...);}
}

6. MyBatis 建造者模式的优势

  • 降低复杂度:将复杂对象的构建逻辑封装在建造者类中,简化了调用者的使用。
  • 提高可维护性:建造者模式使得 MyBatis 的配置和对象创建更具结构化,便于后续的维护和扩展。
  • 灵活性:支持通过多步骤构建对象,并允许在构建过程中动态调整配置。
  • 链式调用:动态 SQL 生成器支持链式调用,代码更简洁直观。

7. 建造者模式的不足

  • 增加类的数量:使用建造者模式会增加类的数量,尤其在大规模项目中,可能导致类层次复杂化。
  • 学习成本:对于不熟悉设计模式的开发者,理解 MyBatis 的建造者模式可能会有一定的学习曲线。

8. 总结

MyBatis 通过建造者模式,在多个核心组件的创建过程中有效地降低了复杂度。无论是 SqlSessionFactory 的构建、Mapper 配置的解析,还是动态 SQL 语句的生成,建造者模式都扮演了重要角色。它不仅提高了代码的复用性和灵活性,还使得整个框架的设计更加模块化和可维护。因此,MyBatis 的建造者模式是其高效、简洁的核心之一。

相关文章:

Mybatis框架之建造者模式 (Builder Pattern)

MyBatis 框架中大量使用了 建造者模式 (Builder Pattern) 来构建复杂的对象&#xff0c;尤其是在 SQL 语句的解析、配置对象的创建以及动态 SQL 的生成 等方面。建造者模式使得 MyBatis 能够更灵活、清晰地构建对象&#xff0c;尤其是那些需要多步创建和配置的复杂对象。 1. 什…...

Java从入门到精通笔记篇(十三)

与流处理 ambda表达式 定义 lambda表达式不能被独立执行&#xff0c;因此必须实现函数式接口&#xff0c;并且会返回一个函数式接口的对象。 可将其语法用下列的方式理解 误区警示 “->”符号是由英文状态下的“-”和“>”组成的&#xff0c;符号之间没有空格。 lambd…...

嵌入式:STM32的启动(Startup)文件解析

相关阅读 嵌入式https://blog.csdn.net/weixin_45791458/category_12768532.html?spm1001.2014.3001.5482 启动文件(Startup File)是嵌入式系统开发中的核心组件之一&#xff0c;它用于初始化系统并为主程序的运行做好准备。在大多数情况下&#xff0c;启动文件是用汇编语言编…...

ElasticSearch学习笔记四:基础操作(二)

一、前言 上一篇文章中我们学习了ES中的基础操作&#xff0c;包括索引和映射&#xff0c;同时也学习了ES中的基础数据类型&#xff0c;今天我们继续学习其他的数据类型。 二、复杂数据类型 1、数组&#xff08;Array&#xff09; 在ES中没有特别指定数据类型&#xff0c;换…...

ODA-em-application.log太大处理

检查oda时发现u01使用率很高&#xff0c;层层排查到是em-application.log文件太大 orcl2:/u01/app/oracle/product/11.2.0.4/dbhome_1/oc4j/j2ee/OC4J_DBConsole_oda1_orcl/logoda1>du -sh * 57G em-application.log 2.2M global-application.log 92M …...

基于现金红包营销活动的开源 AI 智能名片与 S2B2C 商城小程序融合发展研究

摘要&#xff1a;本文深入剖析现金红包这一平台补贴的营销利器在消费场景中的多元应用&#xff0c;并将其与开源 AI 智能名片、S2B2C 商城小程序相融合&#xff0c;探讨其中蕴含的创新模式与商业价值。通过详尽解析各类现金红包的使用条件&#xff0c;阐述如何巧妙运用这些营销…...

远程管理不再难!树莓派5安装Raspberry Pi OS并实现使用VNC异地连接

前言&#xff1a;大家好&#xff01;今天我要教你们如何在树莓派5上安装Raspberry Pi OS&#xff0c;并配置SSH和VNC权限。通过这些步骤&#xff0c;你将能够在Windows电脑上使用VNC Viewer&#xff0c;结合Cpolar内网穿透工具&#xff0c;实现长期的公网远程访问管理本地树莓派…...

React中 setState 是同步的还是异步的?调和阶段 setState 干了什么?

React中 setState 是同步的还是异步的 1. React 的 setState 是异步的2. 为什么 setState 在合成事件和生命周期函数中是异步的3. 为什么 setState 在原生事件和定时器中是同步的4. 为什么要这样设计&#xff1f;调和阶段是什么setState在调和阶段干了什么&#xff1f;总结&…...

【D3.js in Action 3 精译_040】4.4 D3 弧形图的绘制方法

当前内容所在位置&#xff1a; 第四章 直线、曲线与弧线的绘制 ✔️ 4.1 坐标轴的创建&#xff08;上篇&#xff09; 4.1.1 D3 中的边距约定&#xff08;中篇&#xff09;4.1.2 坐标轴的生成&#xff08;中篇&#xff09; 4.1.2.1 比例尺的声明&#xff08;中篇&#xff09;4.1…...

C++设计模式:抽象工厂模式(风格切换案例)

抽象工厂模式&#xff08;Abstract Factory&#xff09;是一种创建型设计模式&#xff0c;其核心思想是&#xff1a;为一组相关或相互依赖的对象提供一个创建接口&#xff0c;而无需指定它们具体的类。简单来说&#xff0c;就是一个工厂可以生产一系列相关的对象。 我们接下来…...

搜维尔科技:Xsens随时随地捕捉,在任何环境下实时录制或捕捉

Xsens随时随地捕捉&#xff0c;在任何环境下实时录制或捕捉 搜维尔科技&#xff1a;Xsens随时随地捕捉&#xff0c;在任何环境下实时录制或捕捉...

爬虫基础总结 —— 附带爬取案例

Crawler —— Learning experience 数据的传输&#xff1a; 在OSI七层模型中&#xff0c;传输层为源主机和目标主机之间提供可靠的数据传输和通信服务&#xff0c;在该层中&#xff0c;有两个重要的协议—— TCP与 UDP协议。 TCP协议&#xff08;传输控制协议&#xff09; …...

图像处理学习笔记-20241118

文章目录 霍夫变换基本原理霍夫变换的步骤使用 OpenCV 实现直线检测示例&#xff1a;标准霍夫变换 示例&#xff1a;概率霍夫变换参数解释霍夫变换检测圆 基于GAN的样本生成GAN的基本原理基于GAN的数据增广流程实现代码示例 同态滤波&#xff08;Homomorphic Filtering&#xf…...

不能打开网页,但能打开QQ、微信(三种方式)

1.VPN错误 下面三个开关全关闭 2.DNS问题 WINR 输入CMD打开命令行 命令行输入 ipconfig/flushdns 重启电脑 3.直接火绒&#xff08;一键修复&#xff09;...

使用 start-local 脚本在本地运行 Elasticsearch

警告&#xff1a;请勿将这些说明用于生产部署 本页上的说明仅适用于本地开发。请勿将此配置用于生产部署&#xff0c;因为它不安全。请参阅部署选项以获取生产部署选项列表。 使用 start-local 脚本在 Docker 中快速设置 Elasticsearch 和 Kibana 以进行本地开发或测试。 此设…...

计算机网络:概述知识点及习题练习

网课资源&#xff1a; 湖科大教书匠 1、因特网 网络之间需要路由器进行互联&#xff0c;互联网是网络的网络&#xff0c;因特网是最大的互联网&#xff0c;连接到网络的设备称为主机&#xff0c;一般不叫路由器为主机。 因特网发展&#xff1a;ARPNET->三级结构因特网&am…...

python蓝桥杯刷题2

1.最短路 题解&#xff1a;这个采用暴力枚举&#xff0c;自己数一下就好了 2.门牌制作 题解&#xff1a;门牌号从1到2020&#xff0c;使用for循环遍历一遍&#xff0c;因为range函数无法调用最后一个数字&#xff0c;所以设置成1到2021即可&#xff0c;然后每一次for循环&…...

在openi平台 基于华为顶级深度计算平台 openmind 动手实践

大家可能一直疑问&#xff0c;到底大模型在哪里有用。 本人从事的大模型有几个方向的业务。 基于生成式语言模型的海事航行警告结构化解析。 基于生成式语言模型的航空航行警告结构化解析。 基于生成式生物序列&#xff08;蛋白质、有机物、rna、dna、mrna&#xff09;的多模态…...

KF UKF

我需要Kalman 现在&#xff0c;主要是用来处理检测问题情况里的漏检&#xff0c;因为模拟了一段2D&#xff0c; &#xff08;x&#xff0c;y&#xff09;的数据&#xff0c;为了看效果&#xff0c;画的线尽量简单一点&#xff1a; import numpy as np import matplotlib.pyplo…...

中伟视界:AI智能分析算法如何针对非煤矿山的特定需求,提供定制化的安全生产解决方案

非煤矿山智能化改造&#xff0c;除了政策文件&#xff0c;上级监管单位需要安装的AI智能分析算法功能之外的&#xff0c;矿方真正关心的&#xff0c;能解决矿方安全生产隐患的AI智能分析算法功能有哪些呢&#xff1f; 经过与矿方的现场交流沟通&#xff0c;收集第一现场人员对安…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

RocketMQ延迟消息机制

两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数&#xff0c;对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后&#xf…...

如何在看板中体现优先级变化

在看板中有效体现优先级变化的关键措施包括&#xff1a;采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中&#xff0c;设置任务排序规则尤其重要&#xff0c;因为它让看板视觉上直观地体…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

HTML 列表、表格、表单

1 列表标签 作用&#xff1a;布局内容排列整齐的区域 列表分类&#xff1a;无序列表、有序列表、定义列表。 例如&#xff1a; 1.1 无序列表 标签&#xff1a;ul 嵌套 li&#xff0c;ul是无序列表&#xff0c;li是列表条目。 注意事项&#xff1a; ul 标签里面只能包裹 li…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...