Qt 小项目 学生管理信息系统

news2024/12/28 3:34:41

主要是对数据库的增删查改的操作

登录/注册界面:

主页面: 

添加信息:

删除信息:

删除第一行(支持多行删除) 

需求分析:

用QT实现一个学生管理信息系统,数据库为MySQL
要求:
- 1、要求有完整界面,如登录界面、信息操作界面
- 2、要求有数据库
- 3、可以录入学生信息
- 4、可以查询学生信息,支持模糊查询
- 5、可以修改学生信息,支持单个和批量修改
- 6、可以删除学生信息,支持单个和批量删除
- 7、学生信息包括:班级、学号、姓名、性别、出生年月、专业、所属学院

2024.11.30 bug和所需添加记录:
- 注册账号时空值也会新建(已解决)
- 数据库sql语句写在qt上,方便运行(已解决)
- 用户名规则,开头字母

2024.12.6 bug记录
- 相同账号和不同密码,弹出信息框错误(已解决)
- 代码耦合:qt数据库常量抽取出来(已解决)
- 添加信息后没有刷新信息

登录界面:

Login.h

#ifndef LOGIN_H
#define LOGIN_H

#include <QWidget>
#include <QSqlDatabase> //数据库驱动
#include <QSqlQuery> //数据库执行语句
#include <QSqlError> //数据库报错
#include <QMessageBox> //消息对话框
#include <QDebug>

QT_BEGIN_NAMESPACE
namespace Ui {
class Login;
}
QT_END_NAMESPACE

class Login : public QWidget
{
    Q_OBJECT

public:
    Login(QWidget *parent = nullptr);
    ~Login();
    void createDataBase();

private slots:
    void on_loginbutton_clicked();

    void on_registerbtn_clicked();

private:
    Ui::Login *ui;
};
#endif // LOGIN_H

Login.cpp

#include "login.h"
#include "ui_login.h"
#include "homepage.h"
#define databaseName "qt"

Login::Login(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Login)
{
    ui->setupUi(this);
    //加载驱动
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("127.0.0.1"); // 主机IP
    db.setUserName("root"); // 用户名
    db.setPassword(""); // 密码

    if (!db.open()) {
        qDebug() << "WARNING: " << db.lastError().text();
        return; // 如果连接失败,退出函数
    }
    // qDebug() << databaseName;
    // 检查数据库 qt 是否存在
    QSqlQuery query;
    if (!query.exec("CREATE DATABASE IF NOT EXISTS " databaseName)) {
        qDebug() << "创建数据库" << databaseName << "失败:" << query.lastError().text();
        return; // 数据库创建失败,退出函数
    }
    else{
        qDebug() << "数据库" << databaseName << "已存在!";
    }

    db.setDatabaseName(databaseName); // 现在切换到 qt 数据库
    if (!db.open()) {
        qDebug() << "WARNING: 无法打开 " << databaseName << "数据库:" << db.lastError().text();
        return; // 如果无法连接到 qt,退出函数
    }

    // 数据库连接成功,继续后续操作
    qDebug() << "成功创建数据库!" << databaseName ;
    createDataBase();
}

//sql语句创建数据库
void Login::createDataBase() {
    // 创建user表的SQL语句
    QString createUserTable = "CREATE TABLE IF NOT EXISTS `user` ("
                              "`account` VARCHAR(20) NOT NULL, "
                              "`pwd` VARCHAR(20) NOT NULL, "
                              "PRIMARY KEY (`account`))";

    // 创建student表的SQL语句
    QString createStudentTable = "CREATE TABLE IF NOT EXISTS `student` ("
                                 "`id` INT(5) NOT NULL, "
                                 "`name` VARCHAR(20) NOT NULL, "
                                 "`gender` VARCHAR(2) NOT NULL, "
                                 "`birthdate` VARCHAR(10) NOT NULL, "
                                 "`major` VARCHAR(20) NOT NULL, "
                                 "`class` VARCHAR(20) NOT NULL, "
                                 "`college` VARCHAR(20) NOT NULL, "
                                 "PRIMARY KEY (`id`))";

    // 执行创建表的SQL语句
    QSqlQuery query;
    if (query.exec(createUserTable) && query.exec(createStudentTable)) {
        qDebug() << "数据库创建成功";
    } else {
        qDebug() << "数据库创建失败" << query.lastError().text();
    }

}

void Login::on_loginbutton_clicked() //登录功能
{
    QString account = ui->account->text();
    QString password = ui->pwd->text();
    QString sql = QString("select * from user where account='%1' and pwd='%2'")
                      .arg(account).arg(password);
    QSqlQuery query(sql);
    if(query.next()){
        QMessageBox::information(this, "登录认证", "登录成功");
        //登录成功后可以跳转到主页面
        HomePage *window = new HomePage();
        window->show();
        this->close(); //关闭登录窗口
    }
    else{
        QMessageBox::information(this, "登录认证", "登录失败,账户或者密码错误");
    }
    // HomePage *window = new HomePage(); //测试专用
    // window->show();
    // this->close(); //关闭登录窗口
}

void Login::on_registerbtn_clicked() //注册按钮
{
    QString account = ui->account->text().trimmed();
    QString password = ui->pwd->text().trimmed();
    //判断账号和密码是否为空
    if(account.isEmpty() || password.isEmpty()){
        QMessageBox::warning(this,"注册认证","账号或密码不能为空!");
        return; //退出函数
    }
    //相同账号,不同密码的情况:
    QString sql = QString("select * from user where account='%1'")
                      .arg(account);
    QSqlQuery query(sql);
    if(query.next()){
        QMessageBox::warning(this,"注册认证","账号已存在!");
        return; //退出函数
    }
    //注册账号
    sql = QString("insert into user(account,pwd) values('%1','%2');")
                      .arg(account).arg(password);
    if(query.exec(sql)){ //表中存在该账号和密码
        QMessageBox::information(this,"注册认证","注册失败!");
    }
    else{
        QMessageBox::information(this,"注册认证","注册成功!");
    }
}

Login::~Login()
{
    delete ui;
}

Login.ui

学生管理信息系统界面:

HomePage.h

#ifndef HOMEPAGE_H
#define HOMEPAGE_H

#include <QWidget>
#include <QSqlDatabase> //数据库驱动
#include <QSqlQuery> //数据库执行语句
#include <QSqlError> //数据库报错
#include <QMessageBox> //消息对话框
#include <QDebug>

namespace Ui {
class HomePage;
}

class HomePage : public QWidget
{
    Q_OBJECT

public:
    explicit HomePage(QWidget *parent = nullptr);
    ~HomePage();

    void initDatabase(); //加载数据库驱动函数
    void refreshTable(QString inquiresql); //刷新表格,查询数据库全部内容

private slots:
    void on_refresh_btn_clicked();

    void on_delete_btn_clicked();

    void on_inquire_btn_clicked();

    void on_add_btn_clicked();

    void on_modify_btn_clicked();

private:
    Ui::HomePage *ui;
};

#endif // HOMEPAGE_H

HomePage.cpp

#include "homepage.h"
#include "ui_homepage.h"
#include "add.h"
#include "modify.h"
#define databaseName "qt"

HomePage::HomePage(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::HomePage)
{
    ui->setupUi(this);

    initDatabase(); //加载数据库驱动
    //设置表头
    QStringList headerList; //定义headerList变量
    headerList << "选择栏" << "学号" << "姓名" << "性别" << "出生年月" << "专业" << "班级" << "学院"; //添加内容
    QFont font; //设置字号
    font.setPointSize(17);
    ui->tableWidget->setFont(font);
    ui->tableWidget->setColumnCount(headerList.size()); //设置列数=表头列数
    ui->tableWidget->setHorizontalHeaderLabels(headerList); //添加headerList到表头

    ui->tableWidget->setRowCount(3); //设置行数,不设置显示不出文本
    // 设置列表自动填充满窗口
    ui->tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    
    // 设置输入框提示信息为占位符文本,一旦用户开始输入,提示信息会消失。
    ui->inquire_lineEdit->setPlaceholderText("支持模糊查询,输入姓名或者学号关键词");

    refreshTable(NULL);
}

void HomePage::initDatabase(){ //加载数据库驱动函数
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("127.0.0.1"); // 主机IP
    db.setUserName("root"); // 用户名
    db.setPassword(""); // 密码
    db.setDatabaseName(databaseName); // 要连接哪个数据库,它的名字
    // 打开数据库,如果打不开就弹出报错对话框
    if(db.open() == false)
    {
        qDebug() << "WARNING:" <<  db.lastError().text() << "\n";
    }
    // 打开成功
    qDebug() << "数据库成功打开" << "\n";
}

void HomePage::refreshTable(QString inquiresql){
    //先【从最后往前】删除表格所有行
    for(int row = ui->tableWidget->rowCount()-1; row >= 0; row--){
        ui->tableWidget->removeRow(row);
    }
    QSqlQuery query;
    if(inquiresql.isEmpty()){
        QString sql = "select * from student";
        query.exec(sql);
    }
    else{
        query.exec(inquiresql);
    }

    //数据库查询并添加
    int row = 0;
    while(query.next()){
        int Old_RowCount = ui->tableWidget->rowCount(); //获取当前表格行数
        ui->tableWidget->setRowCount(Old_RowCount+1); //添加一行

        //第一列添加复选框
        QTableWidgetItem *checkbox = new QTableWidgetItem();
        checkbox->setCheckState(Qt::Unchecked); //设置非选中状态
        ui->tableWidget->setItem(row, 0, checkbox);

        //添加数据,未设置只读状态
        ui->tableWidget->setItem(row, 1, new QTableWidgetItem(query.value(0).toString())); // 学号
        ui->tableWidget->setItem(row, 2, new QTableWidgetItem(query.value(1).toString())); // 姓名
        ui->tableWidget->setItem(row, 3, new QTableWidgetItem(query.value(2).toString())); // 性别
        ui->tableWidget->setItem(row, 4, new QTableWidgetItem(query.value(3).toString())); // 出生年月
        ui->tableWidget->setItem(row, 5, new QTableWidgetItem(query.value(4).toString())); // 专业
        ui->tableWidget->setItem(row, 6, new QTableWidgetItem(query.value(5).toString())); // 班级
        ui->tableWidget->setItem(row, 7, new QTableWidgetItem(query.value(6).toString())); // 学院

        row++; //下一行
    }
}

void HomePage::on_refresh_btn_clicked() //刷新学生信息
{
    QString nullString = NULL;
    refreshTable(nullString); //刷新表格
}

void HomePage::on_delete_btn_clicked() //删除学生信息
{
    QList<QString> StudentId; //存储需要删除的学生id
    //遍历表格每一行
    for(int row = ui->tableWidget->rowCount()-1; row >= 0; row--){
        QTableWidgetItem *checkBoxItem = ui->tableWidget->item(row, 0); //读取勾选框的列表项
        if(checkBoxItem->checkState() == Qt::Checked){
            QTableWidgetItem *idItem = ui->tableWidget->item(row, 1); //读取id的列表项
            if (idItem) {
                StudentId.append(idItem->text());
            }
        }
    }
    //没勾选就不删了,退出函数
    if(StudentId.empty()){
        QMessageBox::information(this, "提示", "请先勾选需要删除的行");
        return;
    }
    //构建批量删除的SQL语句,参数化查询防止SQL注入
    QString sql = "DELETE FROM student WHERE id IN (";
    for (int i = 0; i < StudentId.size(); i++) {
        sql += "?";
        if (i < StudentId.size() - 1)
            sql += ",";
    }
    sql += ")";

    QSqlQuery query;
    query.prepare(sql);
    for (int i = 0; i < StudentId.size(); i++) {
        query.addBindValue(StudentId[i]);
    }

    if(query.exec()) {
        QString nullString = NULL;
        refreshTable(nullString); //删除成功后立即刷新表格
        QMessageBox::information(this, "成功", "删除成功!");
    } else {
        QMessageBox::information(this, "失败", "删除失败:" + query.lastError().text());
    }
}

void HomePage::on_inquire_btn_clicked() //查询信息
{
    QString inquireString = ui->inquire_lineEdit->text().trimmed();
    QString sql = QString("select id, name, gender, birthdate, major, class, college from student where id like \"%1%2\" or name like \"%3%4\"")
                      .arg(inquireString, "%", inquireString, "%");
    refreshTable(sql);
}

void HomePage::on_add_btn_clicked() //添加信息
{
    int Old_RowCount = ui->tableWidget->rowCount(); //获取当前表格行数
    ui->tableWidget->setRowCount(Old_RowCount+1); //添加一行
    add *window = new add();
    window->show();
}

void HomePage::on_modify_btn_clicked() //根据学号修改信息
{
    Modify *window = new Modify();
    window->show();
}

HomePage::~HomePage()
{
    delete ui;
}

HomePage.ui

添加信息界面:

add.h

#ifndef ADD_H
#define ADD_H

#include <QWidget>
#include <QMessageBox> //消息对话框
#include <QDebug>
#include <QSqlDatabase> //数据库驱动
#include <QSqlQuery> //数据库执行语句
#include <QSqlError> //数据库报错

namespace Ui {
class add;
}

class add : public QWidget
{
    Q_OBJECT

public:
    explicit add(QWidget *parent = nullptr);
    ~add();

private slots:
    void on_add_btn_clicked();

private:
    Ui::add *ui;
};

#endif // ADD_H

add.cpp

#include "add.h"
#include "ui_add.h"
#include "homepage.h"

add::add(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::add)
{
    ui->setupUi(this);
}

void add::on_add_btn_clicked()
{
    QString id = ui->id_linedit->text().trimmed();
    QString name = ui->name_lineEdit->text().trimmed();
    QString gender = ui->gender_lineEdit->text().trimmed();
    QString birthdate = ui->birth_lineEdit->text().trimmed();
    QString major = ui->major_lineEdit->text().trimmed();
    QString Class = ui->class_lineEdit->text().trimmed();
    QString college = ui->college_lineEdit->text().trimmed();
    //结束条件
    if(id.isEmpty() || name.isEmpty() || gender.isEmpty()
        || birthdate.isEmpty() || major.isEmpty() || Class.isEmpty() || college.isEmpty()){
        QMessageBox::warning(this, "警告", "信息请填写完整!");
        return;
    }
    //判断学号是否存在,存在则结束
    QString sql = "select * from student where id = ?";
    QSqlQuery query;
    query.prepare(sql);
    query.bindValue("?", id);
    query.exec();
    if(query.next()){
        QMessageBox::warning(this, "警告", "学号已存在!");
        return;
    }
    //添加学生
    sql = QString("insert into student (id, name, gender, birthdate, major, class, college) values (\"%1\", \"%2\", \"%3\", \"%4\", \"%5\", \"%6\", \"%7\")")
              .arg(id, name, gender, birthdate, major, Class, college);

    if(query.exec(sql)) {
        QMessageBox::information(this, "成功", "插入成功!");
        close(); //关闭窗口
        HomePage *homepage = new HomePage();
        homepage->refreshTable(NULL); //刷新表格
    }
    else {
        QMessageBox::information(this, "失败", "插入失败:" + query.lastError().text());
    }
}

add::~add()
{
    delete ui;
}

add.ui

修改信息界面:

Modify.h

#ifndef MODIFY_H
#define MODIFY_H

#include <QWidget>
#include <QMessageBox> //消息对话框
#include <QDebug>
#include <QSqlDatabase> //数据库驱动
#include <QSqlQuery> //数据库执行语句
#include <QSqlError> //数据库报错

namespace Ui {
class Modify;
}

class Modify : public QWidget
{
    Q_OBJECT

public:
    explicit Modify(QWidget *parent = nullptr);
    ~Modify();

private slots:
    void on_modify_btn_clicked();

private:
    Ui::Modify *ui;
};

#endif // MODIFY_H

Modify.cpp

#include "modify.h"
#include "ui_modify.h"
#include "homepage.h"

Modify::Modify(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Modify)
{
    ui->setupUi(this);
}

void Modify::on_modify_btn_clicked()
{
    QString id = ui->id_linedit->text().trimmed();
    QString name = ui->name_lineEdit->text().trimmed();
    QString gender = ui->gender_lineEdit->text().trimmed();
    QString birthdate = ui->birth_lineEdit->text().trimmed();
    QString major = ui->major_lineEdit->text().trimmed();
    QString Class = ui->class_lineEdit->text().trimmed();
    QString college = ui->college_lineEdit->text().trimmed();

    if(id.isEmpty() || name.isEmpty() || gender.isEmpty()
        || birthdate.isEmpty() || major.isEmpty() || Class.isEmpty() || college.isEmpty()){
        QMessageBox::warning(this, "警告", "信息请填写完整!");
        return;
    }

    QSqlQuery query;

    QString sql = QString("update student set name = \"%1\"," "gender =\"%2\", birthdate =\"%3\", major = \"%4\", "
                          "Class = \"%5\", college = \"%6\" where id =%7")
                        .arg(name, gender, birthdate, major, Class, college, id);
    if(query.exec(sql)){
        QMessageBox::information(this, "成功", "修改成功!");
        HomePage *homepage = new HomePage();
        QString nullString = NULL;
        homepage->refreshTable(nullString); //刷新表格
        close(); //关闭窗口
    }
    else{
        QMessageBox::information(this, "失败", "修改失败!");
    }
}

Modify::~Modify()
{
    delete ui;
}

Modify.ui

参考资料:

【C++】C++ QT实现 学生信息管理系统(QT源码)【独一无二】_qt学生管理系统-CSDN博客

如何用qt实现学生信息管理系统_用qtcreater做一个学生信息管理系统-CSDN博客

Qt 学习第十一天:QTableWidget 的使用_qt tablewidget resize-CSDN博客

Qt 学习第十一天:QTableWidget 的使用_qt tablewidget resize-CSDN博客

Qt设计精美的登录注册界面(包含SQLite数据库应用)_qt登录界面设计-CSDN博客

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

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

相关文章

IDEA的service窗口中启动类是灰色且容易消失

大家在学习Spring Cloud的过程中,随着项目的深入,会分出很多个微服务,当我们的服务数量大于等于三个的时候,IDEA会给我们的服务整理起来,类似于这样 但是当我们的微服务数量达到5个以上的时候,再启动服务的时候,服务的启动类就会变成灰色,而且还容易丢失 解决方法 我们按住…

【JMX JVM监控】Prometheus读取Trino的JMX数据到Grafana展示

trino运行拥有自己的UI来监控资源使用率&#xff0c;但领导需要更好的展示做些图表出来放到PPT里面&#xff0c;选择了用prometheus收集数据和grafana来展示图表。本文就trino的数据采集和展示做记录&#xff0c;对于prometheus和grafana的安装不做介绍。 首先要采集trino的数据…

【NIPS2024】Unique3D:从单张图像高效生成高质量的3D网格

背景&#xff08;现有方法的不足&#xff09;&#xff1a; 基于Score Distillation Sampling &#xff08;SDS&#xff09;的方法&#xff1a;从大型二维扩散模型中提取3D知识&#xff0c;生成多样化的3D结果&#xff0c;但存在每个案例长时间优化问题/不一致问题。 目前通过微…

雨晨 26100.2454 Windows 11 24H2 专业工作站 极简纯净版

文件: 雨晨 26100.2454 Windows 11 24H2 专业工作站极简 install.esd 大小: 1947043502 字节 修改时间: 2024年12月6日, 星期五, 16:38:37 MD5: 339B7FDCA0130D432A0E98957738A9DD SHA1: 2978AE0CEAF02E52EC4135200D4BDBC861E07BE8 CRC32: 8C329C89 简述&#xff1a; 由YCDIS…

IDE如何安装插件实现Go to Definition

项目背景 框架&#xff1a;Cucumber Cypress 语言&#xff1a;Javascript IDE&#xff1a;vscode 需求 项目根目录cypress-automation的cypress/integration是测试用例的存放路径&#xff0c;按照不同模块不同功能创建了很多子目录&#xff0c;cucumber测试用例.feature文…

pyqtgraph绘制实时更新数据的图

PyQtGraph是一个基于PyQt和NumPy的Python库&#xff0c;它专为实时数据可视化而设计。以绘制0~2π范围的ysin(x)为例&#xff0c;基本用法的代码如下&#xff1a; # codingutf-8import pyqtgraph as pg from pyqtgraph.Qt import QtGui, QtCore import numpy as np# pyqtgraph…

容器运行应用及Docker命令

文章目录 一、使用容器运行Nginx应用1_使用docker run命令运行Nginx应用1 观察下载容器镜像过程2 观察容器运行情况 2_访问容器中运行的Nginx服务1 确认容器IP地址2 容器网络说明3 使用curl命令访问 二、Docker命令1_Docker命令获取帮助方法2_Docker官网提供的命令说明3_docker…

小身躯大能量-供热系统通过EtherCAT转Profinet网关进行升级

在现代工业自动化领域&#xff0c;通信技术的进步对于提高系统效率、稳定性和可靠性起着至关重要的作用。EtherCAT&#xff08;Ethernet for Control Automation Technology&#xff09;作为一种实时以太网解决方案&#xff0c;因其高性能及成本效益高等特点&#xff0c;在众多…

网络编程(UDP\TCP回显服务器)

目录 套接字socket TCP和UDP特点比较 特点 比较 UDP回显服务器/客户端的编写 UDP的socket api 回显服务器 客户端 TCP回显服务器/客户端的编写 TCP的socket api 回显服务器 客户端 优化服务器 1.关闭服务器创建的socket对象 2.引入线程池&#xff0c;为多个客户…

系统监控——分布式链路追踪系统

摘要 本文深入探讨了分布式链路追踪系统的必要性与实施细节。随着软件架构的复杂化&#xff0c;传统的日志分析方法已不足以应对问题定位的需求。文章首先解释了链路追踪的基本概念&#xff0c;如Trace和Span&#xff0c;并讨论了其基本原理。接着&#xff0c;文章介绍了SkyWa…

burp常用机漏洞测试理论

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&a…

docker学习笔记(四)--DockerFile

文章目录 一、什么是Dockerfile二、docker build命令三、dockerfile指令3.1 FROM3.2 ENV3.3 WORKDIR3.4 RUN3.5 CMD3.6 ENTRYPOINT3.7 EXPOSE3.8 ARG3.9 ADD3.10 COPY3.11 VOLUME 四、dockerfile示例 一、什么是Dockerfile Dockerfile 是用于构建 Docker 镜像的脚本文件&#…

创造未来:The Sandbox 创作者训练营如何赋能全球创造者

创作者训练营让创造者有能力打造下一代数字体验。通过促进合作和提供尖端工具&#xff0c;The Sandbox 计划确保今天的元宇宙是由一个个创造者共同打造。 2024 年 5 月&#xff0c;The Sandbox 推出了「创作者训练营」系列&#xff0c;旨在重新定义数字创作。「创作者训练营」系…

基于Pyhton的人脸识别(Python 3.12+face_recognition库)

使用Python进行人脸编码和比较 简介 在这个教程中&#xff0c;我们将学习如何使用Python和face_recognition库来加载图像、提取人脸编码&#xff0c;并比较两个人脸是否相似。face_recognition库是一个强大的工具&#xff0c;它基于dlib的深度学习模型&#xff0c;可以轻松实…

抽象工厂模式的理解和实践

在软件开发中&#xff0c;设计模式是解决常见问题的最佳实践。抽象工厂模式是一种创建型设计模式&#xff0c;提供了一种创建一系列相关或相互依赖对象的接口&#xff0c;而无需指定它们的具体类。本文将详细解释抽象工厂模式的概念、结构、优点、缺点&#xff0c;并通过Java代…

Hadoop生态圈框架部署 伪集群版(五)- HBase伪分布式部署

文章目录 前言一、Hbase伪分布式部署&#xff08;手动部署&#xff09;1. 下载Hbase2. 上传安装包3. 解压HBase安装包4. 配置HBase配置文件4.1 修改hbase-env.sh配置文件4.2 修改hbase-site.xml配置文件4.3 修改regionservers配置文件4.4 删除hbase中slf4j-reload4j-1.7.33.jar…

【css】基础(二)

本专栏内容为&#xff1a;前端专栏 记录学习前端&#xff0c;分为若干个子专栏&#xff0c;html js css vue等 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;css专栏 &#x1f69a;代码仓库&#xff1a;小小unicorn的代码仓库&#x1f69a; &a…

链式设计模式

链式设计模式——装饰器模式和职责链模式 装饰模式 定义&#xff1a; 指在不改变现有对象结构的情况下&#xff0c;动态地给该对象增加一些职责&#xff08;即增加其额外功能&#xff09;的模式。 结构 装饰&#xff08;Decorator&#xff09;模式中的角色&#xff1a; 抽…

电子电气架构 --- E/E(电子电气架构)的重新定义

我是穿拖鞋的汉子&#xff0c;魔都中坚持长期主义的汽车电子工程师。 老规矩&#xff0c;分享一段喜欢的文字&#xff0c;避免自己成为高知识低文化的工程师&#xff1a; 所谓鸡汤&#xff0c;要么蛊惑你认命&#xff0c;要么怂恿你拼命&#xff0c;但都是回避问题的根源&…

app-1 App 逆向环境准备(mumu模拟器+magisk+LSPosed+算法助手+抓包(socksDroid+charles)+Frida环境搭建

一、前言 本篇是基于 mumu模拟器 进行环境配置记录。&#xff08;真机的后面博客记录&#xff09; 二、mumu模拟器magiskLSPosed算法助手 2.1、mumu模拟器 选择 mumu 模拟器&#xff0c;下载地址&#xff1a;https://mumu.163.com 安装完成后打开&#xff0c;找到设置中心进…