消息队列(3) -封装数据库的操作

前言

上一篇博客我们写了, 关于交换机, 队列,绑定, 写入数据库的一些建库建表的操作 这一篇博客中,我们将建库建表操作,封装一下实现层一个类来供上层服务的调用 , 并在写完该类之后, 测试代码是否完整

实现封装

在写完上述的接口类 与 xml 后, 我们想要 创建一个类 ,来调用 接口类中的各种方法 , 并对数据库完成一些操作

创建DataBaseManager 类

在这个类中, 我们 需要完成对数据库的建库建表操作 , 并封装 一些关于表的增删查改方法(这里说一下, 因为我们使用的数据库是SQLite 是一个文件, 所以当调用建表操作的时候就自动建库了)
实现的方法

  1. init()初始化, 该方法内如果没有表的存在就去创建表
  2. checkDB,检查数据库文件是否存在
  3. createtable 创建表
  4. default 创建一个默认的交换机插入进去
  5. delete数据库文件的删除
  6. 剩下的就是封装 队列 交换机 绑定的方法了

对于各种方法的介绍, 都写进代码里面了 ,自行阅读即可

package com.example.demo.mqServer.dataCenter;import com.example.demo.MqApplication;
import com.example.demo.mqServer.core.Binding;
import com.example.demo.mqServer.core.Exchange;
import com.example.demo.mqServer.core.ExchangeType;
import com.example.demo.mqServer.core.MSGQueue;
import com.example.demo.mqServer.mapper.MateMapper;import java.io.File;
import java.util.List;public class DataBaseManager {private MateMapper mateMapper;// 针对数据库进行初始化public void init() {// 手动获取matemapper 对象mateMapper = MqApplication.context.getBean(MateMapper.class);// 手动的获取到 MetaMapperif (!checkDBExists()) {//如果数据库不存在,就进行建表操作// 先创建一个data目录File dataDir = new File("./data");dataDir.mkdirs();createTable();// 插入默认数据createDefaultData();System.out.println("[DataBaseManager] 数据库初始化完成!");} else {// 数据库已经存在了, 啥都不必做即可System.out.println("[DataBaseManager] 数据库已经存在!");}}// 删除数据库,  及删除文件 也删除目录 public void deleteDB() {File file = new File("./data/meta.db");boolean ret = file.delete();if (ret) {System.out.println("[DataBaseManager] 删除数据库文件成功!");} else {System.out.println("[DataBaseManager] 删除数据库文件失败!");}File dataDir = new File("./data");// 使用 delete 删除目录的时候, 需要保证目录是空的.ret = dataDir.delete();if (ret) {System.out.println("[DataBaseManager] 删除数据库目录成功!");} else {System.out.println("[DataBaseManager] 删除数据库目录失败!");}}// 检查是否存在meta.db 文件private boolean checkDBExists() {File file = new File("./data/meta.db");return file.exists();}// 这个方法用来建表.// 建库操作并不需要手动执行. (不需要手动创建 meta.db 文件)// 首次执行这里的数据库操作的时候, 就会自动的创建出 meta.db 文件来 (MyBatis 帮我们完成的)private void createTable() {mateMapper.createExchangeTable();mateMapper.createQueueTable();mateMapper.createBindingTable();System.out.println("[DataBaseManager] 创建表完成!");}// 给数据库表中, 添加默认的数据.// 此处主要是添加一个默认的交换机.// RabbitMQ 里有一个这样的设定: 带有一个 匿名 的交换机, 类型是 DIRECT.private void createDefaultData() {// 先构建一个交换机Exchange exchange = new Exchange();exchange.setName("");exchange.setType(ExchangeType.direct);exchange.setDurable(true);exchange.setAutoDelete(false);mateMapper.insertExchange(exchange);System.out.println("[DataBaseManager] 创建初始数据完成!");}public void insertExchange(Exchange exchange){mateMapper.insertExchange(exchange);}public List<Exchange> selectAllExchanges(){return mateMapper.selectAllExchanges();}public void deleteExchange(String exchangeName){mateMapper.deleteExchange(exchangeName);}public void insertQueue(MSGQueue queue){mateMapper.insertQueue(queue);}public List<MSGQueue> selectAllQueues(){return mateMapper.selectAllQueues();}public void deleteQueue(String queueName){mateMapper.deleteQueue(queueName);}public void insertBinding(Binding binding){mateMapper.insertBinding(binding);}public List<Binding> selectAllBindings(){return mateMapper.selectAllBindings();}public void deleteBinding(Binding binding){mateMapper.deleteBinding(binding);}
}

另一种获取Bean对象的方式

对DataBaseManager 类的 解释, 我们知道 想要 获取 Bean对象 一般情况下 我们使用的 @Autowired注解, 但是这个类 我们想要手动 来操作, 使用@Autowired 就在一开始就存入了 , 所以我们教大家另一种 获取Bean对象的方式

步骤1: 找到启动类 , 在启动类中添加一个静态成员
public static ConfigurableApplicationContext context;
步骤2: 使用context 等于 run方法结果
步骤3: 在DataBaseManager 中使用 context 来实现对象装配
mateMapper = MqApplication.context.getBean(MateMapper.class);

package com.example.demo;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;@SpringBootApplication
public class MqApplication {// 在启动类创建一个静态成员, 用来手动的获取bean对象public static ConfigurableApplicationContext context;public static void main(String[] args) {context = SpringApplication.run(MqApplication.class, args);}}

对数据库进行单元测试

但我们,每写完一个模块的时候, 我们就应该对该模块就行单元测试 ,
接下来我们对数据库进行单元测试
单元测试是在想要测试的类中点击Generate , 会出现一个Test ,点击Test
在这里插入图片描述
在这里插入图片描述
这个Test(安装Junit的插件-这里就不介绍了) , 然后选择你想要测试的方法,点击OK
在这里插入图片描述
会在Test包中生成对应的类 , 在这个类中加上@SpringBootTest 注解 ,就可以正常使用了
在这里插入图片描述
测试代码如下

package com.example.demo.mqServer.dataCenter;import com.example.demo.MqApplication;
import com.example.demo.mqServer.core.Binding;
import com.example.demo.mqServer.core.Exchange;
import com.example.demo.mqServer.core.ExchangeType;
import com.example.demo.mqServer.core.MSGQueue;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.test.context.SpringBootTest;import java.util.List;import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class DataBaseManagerTest {private DataBaseManager dataBaseManager = new DataBaseManager();// 接下来下面这里需要编写多个 方法 . 每个方法都是一个/一组单元测试用例.// 还需要做一个准备工作. 需要写两个方法, 分别用于进行 "准备工作" 和 "收尾工作"// 使用这个方法, 来执行准备工作. 每个用例执行前, 都要调用这个方法.@BeforeEachpublic void setUp() {// 由于在 init 中, 需要通过 context 对象拿到 metaMapper 实例的.// 所以就需要先把 context 对象给搞出来.MqApplication.context = SpringApplication.run(MqApplication.class);dataBaseManager.init();}// 使用这个方法, 来执行收尾工作. 每个用例执行后, 都要调用这个方法.@AfterEachpublic void tearDown() {// 这里要进行的操作, 就是把数据库给清空~~ (把数据库文件, meta.db 直接删了就行了)// 注意, 此处不能直接就删除, 而需要先关闭上述 context 对象!!// 此处的 context 对象, 持有了 MetaMapper 的实例, MetaMapper 实例又打开了 meta.db 数据库文件.// 如果 meta.db 被别人打开了, 此时的删除文件操作是不会成功的 (Windows 系统的限制, Linux 则没这个问题).// 另一方面, 获取 context 操作, 会占用 8080 端口. 此处的 close 也是释放 8080.MqApplication.context.close();dataBaseManager.deleteDB();}@Testpublic void testInitTable() {// 由于 init 方法, 已经在上面 setUp 中调用过了. 直接在测试用例代码中, 检查当前的数据库状态即可.// 直接从数据库中查询. 看数据是否符合预期.// 查交换机表, 里面应该有一个数据(匿名的 exchange); 查队列表, 没有数据; 查绑定表, 没有数据.List<Exchange> exchangeList = dataBaseManager.selectAllExchanges();List<MSGQueue> queueList = dataBaseManager.selectAllQueues();List<Binding> bindingList = dataBaseManager.selectAllBindings();// 直接打印结果, 通过肉眼来检查结果, 固然也可以. 但是不优雅, 不方便.// 更好的办法是使用断言.// System.out.println(exchangeList.size());// assertEquals 判定结果是不是相等.// 注意这俩参数的顺序. 虽然比较相等, 谁在前谁在后, 无所谓.// 但是 assertEquals 的形参, 第一个形参叫做 expected (预期的), 第二个形参叫做 actual (实际的)Assertions.assertEquals(1, exchangeList.size());Assertions.assertEquals("", exchangeList.get(0).getName());Assertions.assertEquals(ExchangeType.direct, exchangeList.get(0).getType());Assertions.assertEquals(0, queueList.size());Assertions.assertEquals(0, bindingList.size());}private Exchange createExchange(String name){Exchange exchange = new Exchange();exchange.setName(name);exchange.setAutoDelete(false);exchange.setDurable(true);exchange.setType(ExchangeType.fanout);exchange.setArguments("aaa",1);exchange.setArguments("bbb",2);return exchange;}@Testpublic void insertExchange() {Exchange exchange =createExchange("testExchange");dataBaseManager.insertExchange(exchange);// 插入完毕之后, 查询结果List<Exchange> exchangeList = dataBaseManager.selectAllExchanges();Assertions.assertEquals(2, exchangeList.size());Exchange newExchange = exchangeList.get(1);Assertions.assertEquals("testExchange", newExchange.getName());Assertions.assertEquals(ExchangeType.fanout, newExchange.getType());Assertions.assertEquals(false, newExchange.isAutoDelete());Assertions.assertEquals(true, newExchange.isDurable());Assertions.assertEquals(1, newExchange.getArguments("aaa"));Assertions.assertEquals(2, newExchange.getArguments("bbb"));System.out.println("insertExchange测试成功");}@Testpublic void testDeleteExchange() {// 先构造一个交换机, 插入数据库; 然后再按照名字删除即可!Exchange exchange =createExchange("testExchange");dataBaseManager.insertExchange(exchange);List<Exchange> exchangeList = dataBaseManager.selectAllExchanges();Assertions.assertEquals(2, exchangeList.size());Assertions.assertEquals("testExchange", exchangeList.get(1).getName());// 进行删除操作dataBaseManager.deleteExchange("testExchange");// 再次查询exchangeList = dataBaseManager.selectAllExchanges();Assertions.assertEquals(1, exchangeList.size());Assertions.assertEquals("", exchangeList.get(0).getName());System.out.println("testDeleteExchange测试成功");}private MSGQueue createTestQueue(String queueName) {MSGQueue queue = new MSGQueue();queue.setName(queueName);queue.setDurable(true);queue.setAutoDelete(false);queue.setExclusive(false);queue.setArguments("aaa", 1);queue.setArguments("bbb", 2);return queue;}@Testpublic void testInsertQueue() {MSGQueue queue = createTestQueue("testQueue");dataBaseManager.insertQueue(queue);List<MSGQueue> queueList = dataBaseManager.selectAllQueues();Assertions.assertEquals(1, queueList.size());MSGQueue newQueue = queueList.get(0);Assertions.assertEquals("testQueue", newQueue.getName());Assertions.assertEquals(true, newQueue.isDurable());Assertions.assertEquals(false, newQueue.isAutoDelete());Assertions.assertEquals(false, newQueue.isExclusive());Assertions.assertEquals(1, newQueue.getArguments("aaa"));Assertions.assertEquals(2, newQueue.getArguments("bbb"));System.out.println("testInsertQueue测试成功");}@Testpublic void testDeleteQueue() {MSGQueue queue = createTestQueue("testQueue");dataBaseManager.insertQueue(queue);List<MSGQueue> queueList = dataBaseManager.selectAllQueues();Assertions.assertEquals(1, queueList.size());// 进行删除dataBaseManager.deleteQueue("testQueue");queueList = dataBaseManager.selectAllQueues();Assertions.assertEquals(0, queueList.size());System.out.println("testDeleteQueue测试成功");}private Binding createTestBinding(String exchangeName, String queueName) {Binding binding = new Binding();binding.setExchangeName(exchangeName);binding.setMsgQueueName(queueName);binding.setBindingKey("testBindingKey");return binding;}@Testpublic void testInsertBinding() {Binding binding = createTestBinding("testExchange", "testQueue");dataBaseManager.insertBinding(binding);List<Binding> bindingList = dataBaseManager.selectAllBindings();Assertions.assertEquals(1, bindingList.size());Assertions.assertEquals("testExchange", bindingList.get(0).getExchangeName());Assertions.assertEquals("testQueue", bindingList.get(0).getMsgQueueName());Assertions.assertEquals("testBindingKey", bindingList.get(0).getBindingKey());System.out.println("testInsertBinding测试成功");}@Testpublic void testDeleteBinding() {Binding binding = createTestBinding("testExchange", "testQueue");dataBaseManager.insertBinding(binding);List<Binding> bindingList = dataBaseManager.selectAllBindings();Assertions.assertEquals(1, bindingList.size());// 删除Binding toDeleteBinding = createTestBinding("testExchange", "testQueue");dataBaseManager.deleteBinding(toDeleteBinding);bindingList = dataBaseManager.selectAllBindings();Assertions.assertEquals(0, bindingList.size());System.out.println("testDeleteBinding测试成功");}
}

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

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

相关文章

Python的PyHook3插件使用详解

Python的PyHook3插件使用详解 上代码 上代码 def OnMouseEvent(event):print(MessageName:,event.MessageName)print(Message:,event.Message)print(Time:,event.Time)print(Window:,event.Window)print(WindowName:,event.WindowName)print(Position:,event.Position)print(W…

PAT 1065 A+B and C (64bit)

个人学习记录&#xff0c;代码难免不尽人意。 Given three integers A, B and C in (−263,263), you are supposed to tell whether AB>C. Input Specification: The first line of the input gives the positive number of test cases, T (≤10). Then T test cases foll…

uniapp实现支付宝菜单展开与收起

需求实现支付宝类似的效果&#xff1a; 思路&#xff1a; 1.首先建立展开收起按钮&#xff0c;这里使用的是uview里面的icon图标。 2.其次建立展开菜单内容&#xff0c;这里只演示了文本信息&#xff0c;后期引入首页应用。 3.最后写js逻辑&#xff0c;展开收起时改变盒子高度和…

基于STM32设计的出租车计费系统

一、项目介绍 在城市交通中&#xff0c;出租车是一种常见的交通工具。为了方便乘客和司机之间的交易&#xff0c;出租车计费系统被广泛应用于出租车行业。系统能够自动计算乘客的费用&#xff0c;提供准确、方便的计费服务&#xff0c;并且能够记录乘客的行驶数据&#xff0c;…

flink kafka消费者如何处理kafka主题的rebalance

背景&#xff1a; 我们日常使用kafka客户端消费kafka主题的消息时&#xff0c;当消费者退出/加入消费者组&#xff0c;kafka主题分区数有变等事件发生时&#xff0c;都会导致rebalance的发生&#xff0c;此时一般情况下&#xff0c;如果我们不自己处理offset&#xff0c;我们不…

面试题:HTTP Code码及应用场景分析

1xx 消息(临时响应) 属于临时相应&#xff0c;代表所发出的请求已经被接受&#xff0c;需要继续进行处理。只包含状态行和某些可选的响应头信息&#xff0c;并以空行结束。由于 HTTP/1.0 协议中没有定义任何 1xx 状态码&#xff0c;所以除非在某些试验条件下&#xff0c;服务器…

django处理分页

当数据库量比较大的时候一定要分页查询的 在django中操作数据库进行分页 queryset models.PrettyNum.objects.all() #查询所有 queryset models.PrettyNum.objects.all()[0:10] #查询出1-10列 queryset models.PrettyNum.objects.filter(mobile__contains136)[0:10] …

登陆校验解决前端success回调函数始终执行问题

有一串前端js登陆代码&#xff1a; sendRequest:function(){wx.request({url: http://localhost:8080/lf/login/2021/2021,method:POST,success:(res) > {console.log("测试通过")}})} 和后端代码&#xff1a; public Result<Students> logginById(PathVar…

python-opencv对极几何 StereoRectify

OpenCV如何正确使用stereoRectify函数 函数介绍 用于双目相机的立体校正环节中&#xff0c;这里只谈谈这个函数怎么使用&#xff0c;参数具体指哪些函数参数 随便去网上一搜或者看官方手册就能得到参数信息&#xff0c;但是&#xff01;&#xff01;相对关系非常容易出错&…

OpenAI将GPT-4设置为ChatGPT Plus付费用户的默认模型

OpenAI最近为ChatGPT引入了一系列新功能&#xff0c;这些更新旨在增强用户体验&#xff0c;提供更多指导和更多的功能。其中最显著的功能之一是将GPT-4设置为ChatGPT Plus付费用户的默认模型&#xff0c;这意味着付费订阅用户无需手动切换到其他公开可用的语言模型&#xff0c;…

机器学习深度学习——池化层

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——卷积的多输入多输出通道 &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习 希望文章对你们…

1. Git基础知识

文章目录 Git基础知识一、集中式与分布式二、中心服务器三、工作流四、分支实现五、冲突六、Fast forward七、储藏&#xff08;Stashing&#xff09;八、SSH 传输设置九、.gitignore 文件十、Git 命令一览十一、和远端仓库交互 Git基础知识 一、集中式与分布式 Git 属于分布式…

vue3+antd——实现App.vue页面实时获取权限+用户信息的功能——基础积累

之前写过一篇文章关于vue3antd的框架模板&#xff0c;链接如下&#xff1a;http://t.csdn.cn/9dZMS 1.App.vue代码 <template><ConfigProvider :locale"locale"><ThemeProvider is-root v-bind"themeConfig" :apply-style"false&quo…

【单片机】51单片机,晨启科技,板子引脚对应关系

一般引脚: sbit beepP2^4; //将单片机的P2.4端口定义为beep.本口用于屏蔽上电后蜂鸣器响 sbit ledP1^0; //将单片机的P1.0端口定义为led&#xff0c;用于点亮LED-D1 sbit DIG1P0^0; //数码管位选1 sbit DIG2P0^1; //数码管位选2P10xFF;//初始化P1引脚全部置高&a…

【第一阶段】kotlin的when表达式

1.Java 的if /when是语句 kotlin的if/when是表达式&#xff0c;表达式是有返回值的 java中void是个关键字&#xff0c;Unit在kotlin中是个类 2.当使用when语句的时候必须有一个不满足的值即else: fun main() {var week:Int5val info when(week){1->"今天是星期一"…

Transformer学习笔记

Transformer学习笔记 前言前提条件相关介绍Transformer总体架构编码器&#xff08;Encoder&#xff09;位置编码&#xff08;Positional Encoding&#xff09;get_attn_pad_mask函数&#xff08;Padding Mask&#xff09;EncoderLayerMultiHeadAttentionScaledDotProductAttent…

项目出bug,找不到bug,如何拉回之前的版本

1.用gitee如何拉取代码 本文为转载于「闪耀太阳a」的原创文章原文链接&#xff1a;https://blog.csdn.net/Gufang617/article/details/119929145 怎么从gitee上拉取代码 1.首先找到gitee上想要拉取得代码URL地址 点击复制这里的https地址 1 ps:&#xff08;另外一种方法&…

【React重点知识与代码案例】

React是当前最流行的JavaScript前端框架之一&#xff0c;以下是React重要的知识点和代码案例&#xff1a; 1.JSX语法&#xff1a;JSX是React用于描述UI的语法扩展&#xff0c;它允许在JavaScript代码中编写类HTML的代码。例如&#xff1a; const element <h1>Hello, wo…

xcode打包导出ipa

转载&#xff1a;xcode打包导出ipa 目录 转载&#xff1a;xcode打包导出ipa 第一步&#xff1a;注册苹果开发者账号 第二步&#xff1a;下载APP Uploader 第三步&#xff1a;使用xcode打包导出ipa文件&#xff0c;供其他人内测 众所周知&#xff0c;在开发苹果应用时需要使…

Leetcode31 下一个排列

解题思路&#xff1a; 算法过程的第二步&#xff0c;可以变为将[j,end]排序&#xff0c;然后从[j,end)和i进行比较&#xff0c;在区间j,end区间第一个大于nums[i]后&#xff0c;交换即可 public void nextPermutation(int[] nums) {int len nums.length - 1;for(int i len;i…