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

news2025/1/18 13:58:50

前言

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

实现封装

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

创建DataBaseManager 类

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

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

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);

        // 手动的获取到 MetaMapper
        if (!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();

    // 接下来下面这里需要编写多个 方法 . 每个方法都是一个/一组单元测试用例.
    // 还需要做一个准备工作. 需要写两个方法, 分别用于进行 "准备工作" 和 "收尾工作"

    // 使用这个方法, 来执行准备工作. 每个用例执行前, 都要调用这个方法.
    @BeforeEach
    public void setUp() {
        // 由于在 init 中, 需要通过 context 对象拿到 metaMapper 实例的.
        // 所以就需要先把 context 对象给搞出来.
        MqApplication.context = SpringApplication.run(MqApplication.class);
        dataBaseManager.init();
    }

    // 使用这个方法, 来执行收尾工作. 每个用例执行后, 都要调用这个方法.
    @AfterEach
    public void tearDown() {
        // 这里要进行的操作, 就是把数据库给清空~~ (把数据库文件, meta.db 直接删了就行了)
        // 注意, 此处不能直接就删除, 而需要先关闭上述 context 对象!!
        // 此处的 context 对象, 持有了 MetaMapper 的实例, MetaMapper 实例又打开了 meta.db 数据库文件.
        // 如果 meta.db 被别人打开了, 此时的删除文件操作是不会成功的 (Windows 系统的限制, Linux 则没这个问题).
        // 另一方面, 获取 context 操作, 会占用 8080 端口. 此处的 close 也是释放 8080.
        MqApplication.context.close();
        dataBaseManager.deleteDB();
    }

    @Test
    public 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;

    }
    @Test
    public 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测试成功");
    }
    @Test
    public 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;
    }

    @Test
    public 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测试成功");
    }
    @Test
    public 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;
    }

    @Test
    public 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测试成功");

    }

    @Test
    public 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.coloradmin.cn/o/843364.html

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

相关文章

Neety与IO模型简介

Netty与IO模型简介 1、Netty 是由 JBOSS 提供的一个 Java 开源框架&#xff0c;现为 Github 上的独立项目。 2、Netty 是一个异步的、基于事件驱动的网络应用框架&#xff0c;用以快速开发高性能、高可靠性的网络 IO 程序。 3、Netty 主要针对在 TCP 协议下&#xff0c;面向…

2023牛客暑期多校训练营7-c-Beautiful Sequence

思路&#xff1a; &#xff0c;则有&#xff0c;也就是说只要知道A1就可以求任意A。由于A是升序排列&#xff0c;所以对于任意&#xff0c;二进制所包含1的最高位第k位来说&#xff0c;表明与第k位相反&#xff0c;要大一些&#xff0c;所以它的第k位为1&#xff0c;的第k位为…

echarts 柱状图 实例

实例效果&#xff1a; 代码&#xff1a; draw(data1, data2,data3) {var option {// backgroundColor: rgb(10,36,68),tooltip: {trigger: axis,axisPointer: {type: shadow,},formatter: function (params: any, ticket: any, callback: any) {const item params[0];var str…

关于“为爱发电”的一些说明~~

对不起&#xff0c;兄弟们&#xff0c;收费了。。 1. 为什么设置收费 emm...混口饭吃。 也是大龄程序员积在极探索挣钱之路。 2. 都有哪些服务 本专栏的手把手教学资料工程文件&#xff0c;但是近期忙于CMN&#xff0c;可能没时间答疑和讨论&#xff0c;见谅。 另外&#xff0…

知识图谱实战应用23-【知识图谱的高级用法】Neo4j图算法的Cypher查询语句实例

大家好,我是微学AI,今天给大家介绍一下知识图谱实战应用23-【知识图谱的高级用法】Neo4j图算法的Cypher查询语句实例,Neo4j图算法是一套在Neo4j图数据库上运行的算法集合。这些算法专门针对图数据结构进行设计,用于分析、查询和处理图数据。图算法可以帮助我们发现图中的模…

class version 61 java version 17.0.4

class version (javap -verbose xxxx.class)_spencer_tseng的博客-CSDN博客

概念解析 | 合成孔径雷达中运动补偿与自聚焦的关系

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:合成孔径雷达中运动补偿和自聚焦的联系与差别 概念解析 | 合成孔径雷达运动补偿与自聚焦的关系研究 基于二维空变运动补偿的机动平台大斜视SAR稀疏自聚焦方法 一、背景介绍 合成…

qt源码---事件系统之QCoreApplication

上一节分析了qt和windows系统之间的消息的传递&#xff0c;本节着重看一下&#xff0c;qt内部的事件是如何传递的&#xff1f; 1.sendEvent函数 在使用的自定义事件时&#xff0c;有时需要手动抛出一个事件&#xff0c;常用的方式有2种&#xff0c;其一时阻塞式的sendEvent函…

优化手机性能,解决卡顿问题:关闭这3个微信开关,释放内存空间

在日常使用手机的过程中&#xff0c;微信无疑是受欢迎和广泛使用的社交应用之一。然而&#xff0c;由于微信的一些默认设置可能会占用大量内存空间&#xff0c;导致手机性能下降并出现卡顿问题。为了提高手机的运行效果&#xff0c;我们需要注意并关闭这3个微信开关&#xff0c…

面试热题(环形链表II)

给定一个链表&#xff0c;返回链表开始入环的第一个节点。 从链表的头节点开始沿着 next 指针进入环的第一个节点为环的入口节点。如果链表无环&#xff0c;则返回 null。 为了表示给定链表中的环&#xff0c;我们使用整数 pos 来表示链表尾连接到链表中的位置&#xff08;索引…

最后一次模拟考试题解

哦我想这不用看都知道是为了水任务 T1 黑白染色 其实这题有原 什么手写体 md (指 markdown) 分析 首先这题如果你题目没看错的话 ,会发现其实他是 n m n \times m nm 让你求 n n n \times n nn 的区域内的点&#xff08;不会只有我一个人题目看错了罢 然后我们会发现…

Rust 编程小技巧摘选(7)

Rust 编程小技巧(7) 1. 结构体 Display trait 结构体的两种形式&#xff0c;对应的成员取法不同&#xff1b; 前者用 self.成员变量名 self.x, self.y&#xff1b;后者用 self.成员索引号 self.0, self.1, self.2, ...... use std::fmt::Display; use std::fmt::Result; us…

云计算——ACA学习 云计算概述

作者简介&#xff1a;一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​ 目录 写在前面 上章回顾 本章简介 本章目标 一.云计算产生背景 1.信息时代的重点变革…

使用 RKE 方式搭建 K8s 集群并部署 NebulaGraph

本文由社区用户 Albert 贡献&#xff0c;首发于 NebulaGraph 论坛&#xff0c;旨在提供多一种的部署方式使用 NebulaGraph。 在本文&#xff0c;我将会详细地记录下我用 K8s 部署分布式图数据库 NebulaGraph 的过程。下面是本次实践的内容规划&#xff1a; 一到十章节为 K8s 集…

【flink】Chunk splitting has encountered exception

执行任务报错&#xff1a; Chunk splitting has encountered exception 错误信息截图&#xff1a; 完整的错误信息&#xff1a; 16:30:43,911 ERROR org.apache.flink.runtime.source.coordinator.SourceCoordinator [SourceCoordinator-Source: CDC Sourceorg.jobslink.flink…

python爬虫3:requests库-案例1

python爬虫3&#xff1a;requests库-案例1 前言 ​ python实现网络爬虫非常简单&#xff0c;只需要掌握一定的基础知识和一定的库使用技巧即可。本系列目标旨在梳理相关知识点&#xff0c;方便以后复习。 申明 ​ 本系列所涉及的代码仅用于个人研究与讨论&#xff0c;并不会对网…

分享由于找不到vcruntime140_1.dll,无法继续执行代码的几种解决方法

vcruntime140_1.dll是Microsoft Visual C Redistributable for Visual Studio 2015中的一个动态链接库文件。它是用于支持在Windows操作系统上运行使用Visual C编写的应用程序或游戏所必需的文件之一。当出现vcruntime140_1.dll丢失的错误时&#xff0c;通常是由于缺少或损坏了…

Python系统学习1-2-计算机基础,python入门技巧

目录 一、硬件 二、软件&#xff1a;程序文档 三、基础知识 四、python执行过程 五、Pycharm使用技巧 一、硬件 计算机五大部件&#xff1a;运算器&#xff0c;存储器&#xff0c;控制器、输入设备&#xff0c;输出设备。 运算器和控制器 集成在CPU中。 存储&#xff1a…

【笔记】移动光猫改桥接

1. 登录后台 移动光猫的超管和密码&#xff08;百度的&#xff09; 账号&#xff1a;CMCCAdmin 密码&#xff1a;aDm8H%MdA 浏览器访问 192.168.1.1 并登录 2. 选择连接 点击“网络”&#xff0c;在“连接名称”下拉框选择 INTENET_R_VID 字样的连接&#xff0c;并截图备…

java.lang.IllegalArgumentException: Invalid character found in methodname

postman请求异常&#xff1a;java.lang.IllegalArgumentException: Invalid character found in method name. HTTP method names must be tokens