轮子项目--消息队列的实现(3)
上一篇文章中我把一些关键的类以及表示出来,如何对这些类对应的对象进行管理呢?管理分为硬盘和内存上,硬盘又分为数据库(管理交换机,队列和绑定)和文件(管理消息),本文就是讨论的数据库上的管理。
此处为了使用更加方便,简化环境,采用更加轻量的数据库——SQLite,它是一个本地数据库,相当于直接操作本地的硬盘文件。
当在idea中配置好SQLiite数据库后,就需要建库建表,由于把配置依赖准备好之后就会自动的建库,因此我们这里主要关注的是建表,数据库存储的是交换机,队列和绑定,因此应该针对三者建立不同的表。可以根据之前创建的核心类进行设计表。那么上述的建表操作什么时机来执行,可能程序需要反复部署多次,为了简化部署的步骤,可以通过代码,自动完成建表的操作。
为了自动完成建表操作,首先创建一个接口,内有需要建表的方法,然后实现对应的xml文件,通过xml实现接口中的抽象方法。对与建表操作我们使用undata标签。最终,我们根据定义的类建立了三张表,但是对于其中的arguments,由于是Map属性, 为了把arguments 存到数据库中,需要把Map转化为json格式的字符串。
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface MetaMapper {// 三个核心建表方法void createExchangeTable();void createQueueTable();void createBindingTable();
}
当前,是把每个建表语句,都单独的列为一个 update 标签, 并且对应一个 java 方法,能否改成,一个 update 标签中包含多个 建表语句,同时借助一个 java 方法,完成上述多个表的创建呢? MyBatis 支持,一个 标签 中包含多个 sq| 语句的(前提是,搭配 MySQL 或者 Oracle).对于 SQLite,无法做到上述功能的,当你一个 update 标签中,写了多个 create table 语句的时候,只有第一个语句能执行.
如何实现把 arguments 这个键值对,和数据库中的字符串类型相互转换呢? 关键在于, MyBatis 在完成数据库操作的时候,会自动的调用到对象的 getter 和 setter.
- 比如 MyBatis 往数据库中写数据, 就会调用对象的 getter 方法,拿到属性的值,再往数据库中写。如果这个过程中,让 getArquments 得到的结果是 String 类型的,此时,就可以直接把这个数据写到数据库了
- 比如 MyBatis 从数据库读数据的时候,就会调用对象的 setter 方法,把数据库中读到的结果设置到对象的属性中.如果这个过程中,让 setArguments,参数是一个 String,并且在 setArquments 内部针对字符串解析,解析成一个 Map 对象
因此我们需要自己写Exchange类的getArguments和setArguments方法,其中getArguments用于MyBatis 往数据库中写数据,因此将Map转为Json类型的字符串。从数据库读数据之后,构造Exchange对象,会自动调用到setArguments,是把arguments从json格式的字符串转化为Map
第二个参数,用来描述当前 json 字符串, 要转成的 java 对象是什么类型的.如果是个简单类型,直接使用对应类型的类对象即可,如果是集合类这样的复杂类型,可以使用 TypeReference 匿名内部类对象,来描述复杂类型的具体信息,(通过泛型参数来描述的)
对于 交换机 和 队列 这两个表,由于使用 name 作为主键,直接按照 name 进行删除即可,对于绑定来说,此时没有主键,删除操作,其实是针对 exchangeName 和 queueName 两个维度进行筛选.。之后需要在接口中声明三个核心增删方法,然后需要在xml文件中写出insert和delete语句。如下:
其中的#{}:MyBatis 看到这个, 就会通过 getArguments 方法, 来获取到这个参数的内容,此处数据库中期望的类型是 String, 此处也就需要让 getArguments 能够得到 String。
此时,我们把数据库的基本操作已经借助MyBatis封装完成。接下来写一个类整合上面的操作。首先是数据库的初始化,此处使用的是一个普通的方法。数据库的初始化=建库建表 +插入一些默认数据,我们期望, 在咱们的 broker server 启动的时候, 做出下列逻辑判定:
1.如果数据库已经存在了,(表啥的都有了),不做任何操作.
2.如果数据库不存在, 则创建库,创建表,构造默认数据
数据库判断是否存在就判定 meta.db 这个文件是否存在即可。根据以上逻辑编写完成代码之后,发现一些方法涉及到mapper的相关调用,那么此时mapper需要保证是被构造出来的,那么如何进行实例化?Mapper是通过Mybatis进行操作的,换句话说,Mapper已经被注册到spring里面了,直接从spring里面拿到现成的对象。常用是@Autowired,但是前提是外面的类是一个注册在spring中的对象,但是现在并不打算让类是一个Bean对象,因为后面还需要手动进行管理,然后构造整体的结构,因此此时不可以用@Autowired,需要手动的构造。在启动类添加一个静态成员,在下面的main方法中,将run方法的返回结果赋值到静态成员,此时借助这个静态成员可以手动的获取指定的bean对象了。接下来在类中完成接口的三个核心insert和delete方法,可以增加select操作。最后进行测试。
设计单元测试要求,单元测试用例和用例之间是需要相互独立的,互不干扰的。因此可以这样子:每个用例执行之前,先执行一段逻辑,搭建测试的环境,准备好测试用的东西;每个用例执行之后,再执行一段逻辑,把用例执行过程中产生的中间结果的影响给消除掉。即“准备工作”和“收尾工作”,加上注解。
准备工作:对数据库进行初始化操作,由于init方法需要手动获取metaMapper,依赖于context对象,因此在测试用例中也需要context对象.
收尾工作:前面是数据库初始化,因此这里要清空数据库,在清空时注意此处不能直接就删除, 而需要先关闭上述 context 对象!! 此处的 context 对象, 持有了 MetaMapper 的实例, MetaMapper 实例又打开了 meta.db 数据库文件。如果 meta.db 被别人打开了, 此时的删除文件操作是不会成功的 (Windows 系统的限制, Linux 则没这个问题),另一方面, 获取 context 操作, 会占用 8080 端口. 此处的 close 也是释放 8080.
测试工作
首先需要测试init方法,由于init方法已经在上面setUp调用过了,因此直接在测试代码中检查当前数据库的状态即可。直接从数据库中查询. 看数据是否符合预期。什么时符合预期的情况?查交换机表, 里面应该有一个数据(匿名的 exchange); 查队列表, 没有数据; 查绑定表, 没有数据。各自调用select方法进行赋值,得到的结果可以直接打印,但是这样子不够优雅,更好的做法是使用断言,assertEquals()方法用以判定结果是不是相等,里面两个参数,第一个形参叫做 expected (预期的), 第二个形参叫做 actual (实际的)。
其次测试交换机的插入,思路是构造一个交换机,插入到数据库中,再次查询数据库,检查是否符合预期,对于构造交换的的方法,其中有一个参数是setArguments,由于此时的测试并不需要一些返回值,因此需要再写它的set和get方法用于测试。之后应用断言进行结果的查询比对。
测试交换机的删除如下:
同理,DataBaseManager的队列和绑定也是先创建对象,在测试插入和删除。
如何写测试用例更加的严禁呢?
相关文章:

轮子项目--消息队列的实现(3)
上一篇文章中我把一些关键的类以及表示出来,如何对这些类对应的对象进行管理呢?管理分为硬盘和内存上,硬盘又分为数据库(管理交换机,队列和绑定)和文件(管理消息),本文就…...

一文深入了解DeepSeek-R1:模型架构
本文深入探讨了 DeepSeek-R1 模型架构。让我们从输入到输出追踪 DeepSeek-R1 模型,以找到架构中的新发展和关键部分。DeepSeek-R1 基于 DeepSeek-V3-Base 模型架构。本文旨在涵盖其设计的所有重要方面。 📝 1. 输入上下文长度 DeepSeek-R1的输入上下文长…...
秘密信息嵌入到RGB通道的方式:分段嵌or完整嵌入各通道
目录 1. 将秘密信息分为三部分的理由 (1)均匀分布负载 (2)提高鲁棒性 (3)容量分配 2. 不将秘密信息分为三部分的情况 (1)嵌入容量 (2)视觉质量 &#…...
Ai人工智能的未来:趋势、挑战与机遇
Ai人工智能的未来:趋势、挑战与机遇 引言 人工智能(AI)已经成为当代科技发展的核心驱动力,其影响力渗透到各个行业,并塑造了我们未来的社会结构。无论是在医疗、金融、制造业,还是在自动驾驶、智能客服、…...
理解WebGPU 中的 GPUDevice :与 GPU 交互的核心接口
在 WebGPU 开发中, GPUDevice 是一个至关重要的对象,它是与 GPU 进行交互的核心接口。通过 GPUDevice ,开发者可以创建和管理 GPU 资源(如缓冲区、纹理、管线等),并提交命令缓冲区以执行渲染和计算任…...

Java 设计模式之桥接模式
文章目录 Java 设计模式之桥接模式概述UML代码实现 Java 设计模式之桥接模式 概述 桥接模式(Bridge):将抽象部分与它的实现部分分离,使它们都可以独立地变化。通过桥接模式,可以避免类爆炸问题,并提高系统的可扩展性。 UML 核心…...

机器学习(李宏毅)——GAN
一、前言 本文章作为学习2023年《李宏毅机器学习课程》的笔记,感谢台湾大学李宏毅教授的课程,respect!!! 不得不说GAN真是博大精深! 二、大纲 GAN问世基本思想原理剖析Tips of GANGAN的应用Cycle GANEva…...
QT无弹窗运行和只允许运行一个exe
最近做一个小功能,需要后台运行QT程序,无弹窗,并且只允许一个exe运行,不关闭程序,无法2次启动。 main.cpp #include "deleteshotcurveflie.h" #include <QApplication> #include <QSharedMemory&…...

C++ STL 容器
C 的 STL(Standard Template Library) 提供了多种容器,分为以下几类: 序列容器(Sequence Containers)关联容器(Associative Containers)无序关联容器(Unordered Associa…...
开源赋能,智造未来:Odoo+工业物联网,解锁智能工厂新范式——以真实案例解读制造业数字化转型的降本增效密码
工业物联网的机遇与挑战:为什么企业需要Odoo? 《中国智能制造发展研究报告2023》指出,85%的制造企业已启动数字化转型,但超60%面临“数据孤岛、系统割裂、成本高企”的痛点[1]。传统ERP系统难以实时对接产线设备,而定…...
CTF-WEB: 利用iframe标签利用xss,waf过滤后再转换漏洞-- N1ctf Junior display
核心逻辑 // 获取 URL 查询参数的值 function getQueryParam(param) { // 使用 URLSearchParams 从 URL 查询字符串中提取参数 const urlParams new URLSearchParams(window.location.search); // 返回查询参数的值 return urlParams.get(param); } // 使用 DOMPuri…...

K8s组件
一、Kubernetes 集群架构组件 K8S 是属于主从设备模型(Master-Slave 架构),即有 Master 节点负责集群的调度、管理和运维,Slave 节点是集群中的运算工作负载节点。 主节点一般被称为 Master 节点,master节点上有 apis…...
python面试题
以下是一些Python面试题: 一、基础语法 Python中的列表(list)和元组(tuple)有什么区别? 答案: 可变性:列表是可变的,可以修改列表中的元素、添加或删除元素;元组是不可变的,一旦创建就不能修改。语法:列表使用方括号[]定义,元组使用圆括号()定义(单个元素的元组…...
AOS安装及操作演示
文章目录 一、安装node1.1 在 macOS 上管理 Node版本1.1.1 安装 nvm1.1.2 验证 nvm 是否安装成功1.1.3 使用 nvm 安装/切换 Node.js 版本1.1.4 卸载 Node.js 版本 1.2 在 windows 上管理 Node版本1.2.1 安装 nvm-windows1.2.2 安装 Node.js 版本1.2.3 切换 Node.js 版本1.2.4 卸…...
蓝桥杯单片机组第十三届初赛试题-程序题(第2批)
题目到官网看即可,有点久了有些细节记不清了,可能以前发的帖子解释详细一点。 这是我单片机初学的时候写的,像代码结构什么的肯定有可以提升的地方,多多包涵,将就看一下。 i2c文件使用官方的,pcf8591函数…...

企业级高可用 Kubernetes 实践:基于青云 LB 搭建容灾与负载均衡集群全攻略
一、前言 在企业生产环境,k8s高可用是一个必不可少的特性,其中最通用的场景就是如何在 k8s 集群宕机一个节点的情况下保障服务依旧可用。部署高可用k8s集群对于企业级云平台来说是一个根本性的原则,容错、服务可用和数据安全是高可用基础设施的关键。本文是在青云上利用青云…...

Python Pandas(11):Pandas 数据可视化
数据可视化是数据分析中的重要环节,它帮助我们更好地理解和解释数据的模式、趋势和关系。通过图形、图表等形式,数据可视化将复杂的数字和统计信息转化为易于理解的图像,从而便于做出决策。Pandas 提供了与 Matplotlib 和 Seaborn 等可视化库…...
【练习】图论
F. Friendly Group 图中选择一个点-1 边两端点都选择1 边一个端点选择-1 添加链接描述 #include<iostream> using namespace std; #include<vector> #include<cstring> const int N300010; int n,m; vector<int> G[N]; int temp1,temp2; bool vis[N…...

【RAG落地利器】Weaviate、Milvus、Qdrant 和 Chroma 向量数据库对比
什么是向量数据库? 向量数据库是一种将数据存储为高维向量的数据库,高维向量是特征或属性的数学表示。每个向量都有一定数量的维度,根据数据的复杂性和粒度,可以从数十到数千不等。 向量通常是通过对原始数据(如文本、图像、音频、视频等)…...
今日AI和商界事件(2025-02-14)
今日AI大事件主要包括以下几个方面: 一、苹果新品预告 事件概述:苹果CEO蒂姆库克在社交媒体发布7秒视频,配文“准备好迎接家庭的新成员”,并宣布2月19日将有新品发布。知名科技记者马克古尔曼称,新款低端iPhone SE将…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...

让AI看见世界:MCP协议与服务器的工作原理
让AI看见世界:MCP协议与服务器的工作原理 MCP(Model Context Protocol)是一种创新的通信协议,旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天,MCP正成为连接AI与现实世界的重要桥梁。…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
GitHub 趋势日报 (2025年06月06日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 590 cognee 551 onlook 399 project-based-learning 348 build-your-own-x 320 ne…...

基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...