Qt-数据库开发-用户登录、后台管理用户

news2024/11/20 19:42:37

Qt-数据库开发-用户登录、后台管理用户

  • [1] Qt-数据库开发-用户登录、后台管理用户
    • 1、概述
    • 2、实现效果
  • [2] Qt使用SqlLite实现权限管理
    • 初始化数据库
    • 创建数据表
    • 插入数据
    • 可使用结构体对数据信息进行封装
    • 数据库查询函数为
    • 数据库更新数据函数为
    • 删除数据函数为
  • [3] 测试效果


[1] Qt-数据库开发-用户登录、后台管理用户

原文链接:https://blog.csdn.net/qq_43627907/article/details/128265671

1、概述

开发环境说明

系统:Windows10、Ubuntu20.04
Qt版本:V5.12.5
编译器:MSVC2017-64、GCC/G++64

2、实现效果

  • 通过按键新建 空白数据行;
  • 使用自增Key;
  • 通过按键更新数据;
  • 判断表是否存在,不存在则创建。
  • 用户登录功能,默认创建超级管理员账号root
  • 支持用户后台管理,通过后台创建、修改、删除用户
  • 用户分为超级管理员、普通管理员、普通用户三个等级;
  • 超级管理员有所有权限,可创建、修改、删除普通管理员、普通用户;
  • 普通管理员可创建、修改、删除普通用户,可新建、修改、查询数据;
  • 普通用户不可修改用户信息,不可新建、修改数据库信息,只可查询。
    实现效果如下:
    在这里插入图片描述
    3、主要代码
    啥也不说了,直接上代码,一切有注释

pro文件: Qt使用到数据库,上来什么都别管,先在pro文件添加上QT += sql ;

dialog.cpp文件:登录界面

#include "dialog.h"
#include "ui_dialog.h"

#include <QSqlQuery>
#include <qmessagebox.h>
#include <QDebug>



bool Dialog::m_loggedIn = false;                           // 登录状态
QString Dialog::m_userName;                                // 登录的用户名
UserBackstage::UserType Dialog::m_userType;                // 用户类型

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

    this->setWindowTitle("登录");

    m_db = QSqlDatabase::addDatabase("QSQLITE");  // 使用数据库驱动(Qsqlite)和默认连接名称(qt_sql_default_connection)添加一个数据库
    m_db.setDatabaseName("SignIn.db");        // 使用文件数据库(可生成数据库文件,数据一直有效)

    if(!m_db.open())             // 打开数据库
    {
        QMessageBox::critical(nullptr, "Error", "打开数据库失败!");
        return ;
    }

    // 创建一个用于保存用户信息的表
    if(!isTableExists("User"))
    {
        QSqlQuery query;

        // 创建一个表person,包含id、firstname、lastname三个字段
        bool ret = query.exec("create table User ("
                   "id         integer primary key,"    // 索引(自增key)
                   "userName   varchar(20),"            // 用户名
                   "password   varchar(20),"            // 密码
                   "type       int)");                  // 用户类型
        if(!ret)
        {
            qDebug() << "创建表失败:";
        }
        else
        {
            QSqlQuery query;
            query.prepare("insert into User(userName, password, type)"
                          "values (:userName, :password, :type)");
            query.bindValue(":userName", "root");
            query.bindValue(":password", "123456");
            query.bindValue(":type", int(UserBackstage::Root));
            query.exec();
        }
    }
}

Dialog::~Dialog()
{
    if(m_db.isOpen())
    {
        m_db.close();       // 关闭数据库
    }
    delete ui;
}

/**
 * @brief   返回登录状态
 * @return  true登录 false未登录
 */
bool Dialog::loggedIn()
{
    return m_loggedIn;
}

/**
 * @brief   返回登录的用户名
 * @return  如果没有则为空
 */
QString Dialog::userName()
{
    return m_userName;
}

/**
 * @brief   返回登录的用户类型
 * @return
 */
UserBackstage::UserType Dialog::type()
{
    return m_userType;
}

/**
 * @brief         判断表是否存在
 * @param table
 * @return
 */
bool Dialog::isTableExists(const QString &table)
{
    QSqlQuery query;
    QString sql = QString("select * from sqlite_master where name = '%1';").arg(table);  // 查询sqlite_master表中是否存在表名
    if(query.exec(sql))
    {
        return query.next();
    }
    return false;
}

/**
 * @brief 登录
 */
void Dialog::on_but_signIn_clicked()
{
    QString userName = ui->line_user->text().trimmed();
    QString password = ui->line_password->text().trimmed();
    if(userName.isEmpty())
    {
        QMessageBox::about(this, "注意!", "用户名不能为空");
        return;
    }
    if(password.isEmpty())
    {
        QMessageBox::about(this, "注意!", "用户密码不能为空");
        return;
    }

    // 从数据库中查询用户和密码,完成登录功能
    QSqlQuery query;
    QString sql = QString("select * from User where userName = '%1';").arg(userName);  // 查询用户
    if(query.exec(sql))
    {
        if(query.next())   // true则用户存在
        {
            if(password == query.value("password").toString())   // 密码相等
            {
                m_userName = userName;
                m_userType = UserBackstage::UserType(query.value("type").toInt());
                m_loggedIn = true;
                this->close();
            }
            else
            {
                QMessageBox::about(this, "注意", "输入密码错误!");
            }
        }
        else
        {
            QMessageBox::about(this, "注意", "用户不存在!");
        }
    }
    else
    {
        QMessageBox::about(this, "注意", "sql指令执行失败!");
    }
}

widget.cpp文件: 数据显示界面

#include "widget.h"
#include "ui_widget.h"
#include "dialog.h"
#include "userbackstage.h"
#include <QMessageBox>
#include <QSqlDatabase>
#include <QDebug>

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

    QString user;
    switch (Dialog::type())
    {
    case UserBackstage::User:
    {
        ui->but_user->setVisible(false);                                    // 隐藏用户管理功能
        ui->but_add->setVisible(false);                                     // 隐藏数据新建功能
        ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);  // 普通用户禁用修改数据功能
        user = QString("普通用户:%1").arg(Dialog::userName());
        break;
    }
    case UserBackstage::Admin:
    {
        user = QString("普通管理员:%1").arg(Dialog::userName());
        break;
    }
    case UserBackstage::Root:
    {
        user = QString("超级管理员:%1").arg(Dialog::userName());
        break;
    }
    }
    this->setWindowTitle(QString("QSql-用户登录Demo - V%1  %2").arg(APP_VERSION).arg(user));
}

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


void Widget::on_but_connect_clicked()
{
    if(ui->but_connect->text() == "关闭数据库")
    {
        ui->but_connect->setText("连接数据库");

        m_db.close();

    }
    else
    {

        m_db = QSqlDatabase::addDatabase("QSQLITE");  // 使用数据库驱动(Qsqlite)和默认连接名称(qt_sql_default_connection)添加一个数据库
//        qDebug() << QSqlDatabase::defaultConnection;           // 打印默认数据库连接名称
        m_db.setDatabaseName("SignIn.db");        // 使用文件数据库(可生成数据库文件,数据一直有效)

        if(!m_db.open())             // 打开数据库
        {
            QMessageBox::critical(nullptr, "Error", "打开数据库失败!");
            return ;
        }

        // 如果表不存在则创建表
        if(!isTableExists("person"))
        {
            QSqlQuery query;

            // 创建一个表person,包含id、firstname、lastname三个字段
            bool ret = query.exec("create table person ("
                       "id         integer primary key,"    // 索引(自增key),使用integer默认为自增, int不能设置主键自增
                       "firstname  varchar(20),"         // 名
                       "lastname   varchar(20))");       // 姓
            if(!ret)
            {
                qDebug() << "创建表失败:";
            }
        }

        initModel();

        ui->but_connect->setText("关闭数据库");
    }
}

/**
 * @brief        判断表是否存在
 * @param table  表名称
 * @return       true存在 false不存在
 */
bool Widget::isTableExists(const QString &table)
{
    QSqlQuery query;
    QString sql = QString("select * from sqlite_master where name = '%1';").arg(table);  // 查询sqlite_master表中是否存在表名
    if(query.exec(sql))
    {
        return query.next();
    }
    return false;
}

/**
 * @brief SQL 表模型(QSqlTableModel)来编辑数据库中的信息
 */
void Widget::initModel()
{
    if(m_model)
    {
        m_model->clear();
        delete m_model;
        m_model = nullptr;
    }
    m_model = new QSqlTableModel(this, m_db);
    m_model->setTable("person");                                // 设置需要显示的数据库表
#if 1
    m_model->setEditStrategy(QSqlTableModel::OnFieldChange);    // 在界面上修改后数据立刻保存到数据库
#else
    m_model->setEditStrategy(QSqlTableModel::OnManualSubmit);   // 将将编辑数据库中值的策略设置为[在调用 submitAll() 或 revertAll() 之前,所有更改都将缓存在模型中(即在界面上修改数据后不会立刻存入数据库)]
#endif
    m_model->setHeaderData(0, Qt::Horizontal, "ID");
    m_model->setHeaderData(1, Qt::Horizontal, "名称");
    m_model->setHeaderData(2, Qt::Horizontal, "姓氏");
    ui->tableView->setModel(m_model);
}

/**
 * @brief 添加空白数据行
 */
void Widget::on_but_add_clicked()
{
    QSqlQuery query;
    query.prepare("insert into person(firstname, lastname)"       // 写入数据时不需写入id字段,实现自增
                  "values (:firstname, :lastname)");
    query.bindValue(":firstname", "");
    query.bindValue(":lastname", "");
    query.exec();
    m_model->select();                                           // 获取数据库中的数据
}

/**
 * @brief 查询数据库更新界面
 */
void Widget::on_but_read_clicked()
{
    if(!m_model) return;
    m_model->select();                                         // 获取数据库中的数据
    ui->tableView->resizeColumnsToContents();                  // 根据表格中的内容自动调整列宽
}

void Widget::on_but_user_clicked()
{
    UserBackstage user;
    user.setUserType(Dialog::type());
    user.exec();
}

userbackstage.cpp文件: 用户管理后台

#include "userbackstage.h"
#include "ui_userbackstage.h"
#include <QDebug>
#include <qmessagebox.h>
#include <qsqlquery.h>

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

    m_model = new QSqlTableModel(this);
    m_model->setTable("User");                                // 设置需要显示的数据库表
    ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    m_model->setHeaderData(0, Qt::Horizontal, "ID");
    m_model->setHeaderData(1, Qt::Horizontal, "用户名");
    m_model->setHeaderData(2, Qt::Horizontal, "密码");
    m_model->setHeaderData(3, Qt::Horizontal, "用户类型");
    ui->tableView->setModel(m_model);

    m_model->select();                                         // 获取数据库中的数据
    ui->tableView->resizeColumnsToContents();                  // 根据表格中的内容自动调整列宽
}

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

/**
 * @brief       设置登录的用户类型
 * @param type
 */
void UserBackstage::setUserType(UserBackstage::UserType type)
{
    m_userType = type;

    // 添加用户类型
    ui->com_type->clear();
    switch (type)
    {
    case User:
    {
        break;
    }
    case Admin:
    {
        ui->com_type->addItem("普通用户", User);
        m_model->setFilter(QString("type = '%1'").arg(int(User)));     // 只显示普通用户的信息
        break;
    }
    case Root:
    {
        ui->com_type->addItem("普通用户", User);
        ui->com_type->addItem("管理员", Admin);
        break;
    }
    }
}

/**
 * @brief 设置用户信息
 */
void UserBackstage::on_but_set_clicked()
{
    QString userName = ui->line_user->text().trimmed();
    QString password = ui->line_password->text().trimmed();
    UserType userType = UserType(ui->com_type->currentIndex());
    if(userName.isEmpty())
    {
        QMessageBox::about(this, "注意!", "用户名不能为空");
        return;
    }
    if(password.isEmpty())
    {
        QMessageBox::about(this, "注意!", "用户密码不能为空");
        return;
    }

    QSqlQuery query;
    QString sql = QString("select * from User where userName = '%1';").arg(userName);  // 查询用户
    if(query.exec(sql))
    {
        if(query.next())   // true则用户存在则更新数据
        {
            int type = query.value("type").toInt();
            if(type >= m_userType)         // 如果修改的用户等级超过登录用户等级,则修改失败
            {
                return;
            }
            sql = QString("update User set password='%1', type=%2  where userName = '%3';")
                    .arg(password)
                    .arg(int(userType))
                    .arg(userName);
            query.exec(sql);
        }
        else               // 用户不存在则插入数据
        {
            query.prepare("insert into User(userName, password, type)"
                          "values (:userName, :password, :type)");
            query.bindValue(":userName", userName);
            query.bindValue(":password", password);
            query.bindValue(":type", int(userType));
            query.exec();
        }
        m_model->select();                                         // 获取数据库中的数据
    }
    else
    {
        qDebug() << "指令执行失败";
    }
}

/**
 * @brief 删除用户信息
 */
void UserBackstage::on_but_delete_clicked()
{
    QString userName = ui->line_user->text().trimmed();
    if(userName.isEmpty())
    {
        QMessageBox::about(this, "注意!", "用户名不能为空");
        return;
    }
    QSqlQuery query;
    QString sql = QString("delete from User where userName = '%1';").arg(userName);  // 查询用户
    if(query.exec(sql))
    {
        m_model->select();                                         // 获取数据库中的数据
    }
    else
    {
        qDebug() << "指令执行失败";
    }
}

[2] Qt使用SqlLite实现权限管理

https://blog.csdn.net/weixin_41377572/article/details/127719446?ops_request_misc=&request_id=&biz_id=102&utm_term=qt%20%E6%9D%83%E9%99%90%E7%AE%A1%E7%90%86&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-0-127719446.142v86insert_down1,239v2insert_chatgpt&spm=1018.2226.3001.4187

根据Sqlite轻量级数据库的优势,便于对于数据进行增删改查等操作。
本例模拟权限列表对不同界面进行权限管理,管理员针对不同人员进行权限设定,灵活性更高。
动态演示效果如下:
在这里插入图片描述
考虑数据库数据安全,可进行哈希散列值计算进行加密,Qt提供QCryptographicHash类进行数据加密,本例中使用的加密函数为:

QString SqlHelper::encode(QString str) {
	QString strPwdSha = "";
	if (str == "") {
		return "";
	}
	QByteArray bytePwd = str.toLatin1();
	QByteArray bytePwdSha = QCryptographicHash::hash(bytePwd, QCryptographicHash::Sha256);
	strPwdSha = bytePwdSha.toHex().toUpper();
	return strPwdSha;
}
QString SqlHelper::encodePwd(QString str) {
	if (str == "") {
		return "";
	}
	QString endata = encode(str);
	QString strdata = "";
	for (int i = 0; i < endata.size(); i++) {
		if (i % 4 == 0) {
			strdata += endata[i];
		}
	}
	return strdata + "SAP";
}

初始化数据库

void SqlHelper::connectDataBase() {
	db = QSqlDatabase::addDatabase("QSQLITE", "sqlite1");// 驱动类型,连接名(默认)
	db.setDatabaseName("DbData/data.db");
	db.setHostName("localhost.");
	db.setUserName("root");
	db.setPassword("123456");
	m_DbState = db.open();
}

创建数据表

void SqlHelper::IniSql() {
	QSqlQuery query(db);
	QString strCmd = QString("create table employee(employee_id varchar(64) primary key,"
		"employee_name varchar(64),employee_pass varchar(32),employee_settingrole varchar(16),"
		"employee_menurole varchar(16),employee_logrole varchar(16),employee_sex varchar(16))");
	query.prepare(strCmd);
	if (query.exec())
	{
		qDebug() << "----employee 数据库表:创建成功!";
		insertData("admin", "root", "root123456", 1,1,1,"male");
	}
	else {
		qDebug() << "----employee 数据表已经存在-----";
	}
}

插入数据

bool SqlHelper::insertData(QString userid, QString username, QString userpass, int sflag, int mflag, int lflag, QString usersex) {
	if (!m_DbState) {
		return false;
	}
	QList<employeeInfo> list = queryAllInfo();
	m_mutex.lock();
	bool flag = false;
	//qDebug() << "m_id:  " << m_id;
	QSqlQuery query(db);
	QString str = QString("insert into employee values(?,?,?,?,?,?,?)");
	query.prepare(str);
	//query.bindValue(0, list.size() + 1);
	query.bindValue(0, userid);
	query.bindValue(1, username);
	QString pass = encodePwd(userpass);
	query.bindValue(2, pass);
	QString setrole = userid;
	setrole.append(QString::number(sflag));
	setrole = encodeRole(setrole,RoleType::SettingRole);
	query.bindValue(3, setrole);
	QString mrole = userid;
	mrole.append(QString::number(mflag));
	mrole = encodeRole(mrole, RoleType::MenuRole);
	query.bindValue(4, mrole);
	QString lrole = userid;
	lrole.append(QString::number(lflag));
	lrole = encodeRole(lrole, RoleType::LogRole);
	query.bindValue(5, lrole);
	query.bindValue(6, usersex);
		if (query.exec()) {
		qDebug() << "插入数据成功----";
		flag = true;
	}
	else {
		qDebug() << "插入数据失败----";
	}
	m_mutex.unlock();
	//qDebug() << "777777777777777777777777";
	return flag;
}

可使用结构体对数据信息进行封装

struct employeeInfo {
	QString employee_id = "";
	QString employee_name;
	QString employee_pass;
	QString employee_settingrole;
	QString employee_menurole;
	QString employee_logrole;
	QString employee_sex;
}; 

数据库查询函数为

QList<employeeInfo> SqlHelper::queryAllInfo() {
	QList<employeeInfo> list;
	if (!m_DbState) {
		return list;
	}
	m_mutex.lock();
	QSqlQuery query(db);
	QString str = "select * from employee";
	query.prepare(str);
	if (query.exec()) {
		while (query.next()) {
			//qDebug() << "name---" << query.value(1).toString() << " age-" << query.value(2).toInt();
			employeeInfo employee;
			employee.employee_id = query.value(0).toString();
			employee.employee_name = query.value(1).toString();
			employee.employee_pass = query.value(2).toString();
			employee.employee_settingrole = query.value(3).toString();
			employee.employee_menurole = query.value(4).toString();
			employee.employee_logrole = query.value(5).toString();
			employee.employee_sex = query.value(6).toString();
			list.append(employee);
		}
	}
	m_mutex.unlock();
	return list;
}
employeeInfo SqlHelper::queryOne(QString userid) {
	employeeInfo employee;
	if (!m_DbState) {
		return employee;
	}
	m_mutex.lock();
	QSqlQuery query(db);
	QString str = "select * from employee where employee_id =?";
	query.prepare(str);
	query.addBindValue(userid);
		if (query.exec()) {
		while (query.next()) {
			employee.employee_id = query.value(0).toString();
			employee.employee_name = query.value(1).toString();
			employee.employee_pass = query.value(2).toString();
			employee.employee_settingrole = query.value(3).toString();
			employee.employee_menurole = query.value(4).toString();
			employee.employee_logrole = query.value(5).toString();
			employee.employee_sex = query.value(6).toString();
		}
	}
	m_mutex.unlock();
	return employee;
}

数据库更新数据函数为

bool SqlHelper::updateData(QString userid, QString username, QString userpass, int sflag ,int mflag, int lflag, QString usersex) {
	if (!m_DbState) {
		return false;
	}
	QSqlQuery query(db);
	QString str = "update employee set employee_name =?,employee_pass=?,"
		"employee_settingrole=?,employee_menurole=?,employee_logrole=? , employee_sex = ? where employee_id =?";
	query.prepare(str);
	query.addBindValue(username);
	QString ss = queryPass(userid);
	m_mutex.lock();
	bool flag = false;
	if (ss == userpass) {
		query.addBindValue(ss);
	}
	else {
		userpass = encodePwd(userpass);
		query.addBindValue(userpass);
	}
	QString nsr = userid;
	nsr.append(QString::number(sflag));
	nsr = encodeRole(nsr, RoleType::SettingRole);
	query.addBindValue(nsr);
	QString nmr = userid;
	nmr.append(QString::number(mflag));
	nmr = encodeRole(nmr, RoleType::MenuRole);
	query.addBindValue(nmr);
	QString nlr = userid;
	nlr.append(QString::number(lflag));
	nlr = encodeRole(nlr, RoleType::LogRole);
	query.addBindValue(nlr);
	query.addBindValue(usersex);
	query.addBindValue(userid);
	if (query.exec()) {
		flag = true;
		qDebug() << "更新成功---";
	}
	else {
		flag = false;
		qDebug() << "更新失败---";
	}
	m_mutex.unlock();
	return flag;
}

删除数据函数为

bool SqlHelper::deleteData(QString userid) {
	if (!m_DbState) {
		return false;
	}
	employeeInfo one = queryOne(userid);
	if (one.employee_id == "") {
		qDebug() << "此人已删除----";
		return false;
	}
	m_mutex.lock();
	bool flag = false;
	QSqlQuery query(db);
	QString str = "delete from employee where employee_id=?";
	query.prepare(str);
	query.addBindValue(userid);
	if (query.exec()) {
		flag = true;
		qDebug() << "删除成功---";
	}
	else {
		flag = false;
		qDebug() << "删除失败---";
	}
	m_mutex.unlock();
	return flag;
}

[3] 测试效果

“loginform.h”

#ifndef LOGINFORM_H
#define LOGINFORM_H

#include <QDialog>
#include <QDebug>

namespace Ui {
class LoginForm;
}

class LoginForm : public QDialog
{
    Q_OBJECT
public:
    enum UserType {
        User,            // 普通用户
        Admin,           // 普通管理员
        Root             // 超级管理员(唯一)
    };
public:
    explicit LoginForm(QWidget *parent = nullptr);
    ~LoginForm();

    static bool loggedIn();
    static QString userName();
    static UserType type();

private slots:
    void on_pBtn_Confirm_clicked();

    void on_pBtn_Cancel_clicked();

private:
    Ui::LoginForm *ui;
    static UserType m_userType;     //当前用户类型
    static bool    m_loggedIn;      // 登录状态
    static QString m_userName;      // 登录的用户名
};

#endif // LOGINFORM_H

“loginform.cpp”

#include "loginform.h"
#include "ui_loginform.h"

LoginForm::UserType LoginForm::m_userType = LoginForm::UserType::User;  //默认状态为普通用户
bool LoginForm::m_loggedIn = false; //默认状态为非登录状态
QString LoginForm::m_userName = "";

LoginForm::LoginForm(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::LoginForm)
{
    ui->setupUi(this);
    setWindowTitle(tr("用户登录"));
    //setWindowFlags(Qt::FramelessWindowHint);
    ui->lineEdit_UserName->clear();
    ui->lineEdit_Passwd->clear();
}

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

bool LoginForm::loggedIn()
{
    return m_loggedIn;
}

QString LoginForm::userName()
{
    return m_userName;
}

LoginForm::UserType LoginForm::type()
{
    return m_userType;
}

void LoginForm::on_pBtn_Confirm_clicked()
{
    QString name = ui->lineEdit_UserName->text().trimmed();
    QString passwd = ui->lineEdit_Passwd->text().trimmed();

    m_userName = name;
    m_loggedIn = true;
    m_userType = UserType::Root;

//    qDebug()<<"Name: "<<name<<"\t passwd: "<<passwd;
    this->close();
}


void LoginForm::on_pBtn_Cancel_clicked()
{
    this->close();
}

在这里插入图片描述

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

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

相关文章

最详细的静态路由的原理和配置

第四章&#xff1a;静态路由 转发数据包是路由器的最主要功能。路由器转发数据包时需要查找路由表&#xff0c;管理员可以通过手工的方法在路由器中直接配置路由表&#xff0c;这就是静态路由。虽然静态路由不适合于在大的网络中使用&#xff0c;但是由于静态路由简单、路由器…

亚马逊云科技让数十亿的数据清洗、转移和查询只需要10分钟

随着数字经济对经济社会的发展贡献愈渐增多&#xff0c;数字金融作为数字经济的有机组成部分和重要支撑&#xff0c;也正成为金融领域竞争与合作的制高点。但在数据要素推动数字金融高速发展的同时&#xff0c;逐渐复杂的互联网环境与日益增强的金融监管力度&#xff0c;对数字…

FL Studio21最新中文版本下载及详细安装教程

FL Studio21最新中文版本是一款专业的音乐制作软件&#xff0c;软件支持录音、音频剪辑、混音、编曲等众多实用功能&#xff0c;可以让你的电脑化身为专业的录音室&#xff0c;进行音乐的录制和剪辑工作&#xff0c;帮助用户轻松创作出各种优秀的音乐作品。 FL Studio21中文版…

亚马逊云科技携手普华永道,推出健康及生命科学行业出海合规指南

自2022年起&#xff0c;国内医疗健康行业的投融资热度略有降低。但医疗行业投资结构正面临转型&#xff0c;投资逐步呈现全球化布局的趋势&#xff0c;在跨境合作领域仍持续释放活力。同时&#xff0c;随着药品集采、医保谈判持续推进&#xff0c;越来越多的中国健康及生命科学…

基于RK3588+TensorFlow的人工智能跨模态行人重识别方法及应用

摘要&#xff1a; 跨模态行人重识别技术&#xff08;cm-ReID&#xff09;旨在可见光、红外等不同模态图像中识别出同一个人&#xff0c;其在人 机协同、万物互联、跨界融合、万物智能的智能系统与装备中有重要应用。提出一种数据增强的跨模态行人 重识别方法&#xff0c;在波长…

【Vue 基础】尚品汇项目-10-Search模块中商品分类与过渡动画

一、商品导航的显示与隐藏 打开“src/componetnts/TypeNav/index.vue”&#xff0c;让商品导航默认为显示 在TypeNav组件挂载完毕时&#xff0c;判断当前的路由是否是“/home”&#xff0c;如果不是“/home”&#xff0c;就将分类导航隐藏 当鼠标移入时 移入时让商品导航显示 …

如何在Windows上轻松安全的将数据从HDD迁移到SSD?

当你打算升级硬盘时&#xff0c;如何将数据从HDD迁移到SSD&#xff1f;你可以使用一款免费的软件将所有数据从一个硬盘克隆到另一个硬盘。 为什么要将数据从HDD迁移到SSD&#xff1f; HDD&#xff08;机械硬盘&#xff09;和SSD&#xff08;固态硬盘&#xff09;是目前常用…

java 学习日记

今天先搞题目 给你一个points 数组&#xff0c;表示 2D 平面上的一些点&#xff0c;其中 points[i] [xi, yi] 。 连接点 [xi, yi] 和点 [xj, yj] 的费用为它们之间的 曼哈顿距离 &#xff1a;|xi - xj| |yi - yj| &#xff0c;其中 |val| 表示 val 的绝对值。 请你返回将所…

DS1302芯片介绍

低功耗时钟芯片DS1302可以对年、月、日、时、分、秒进行计时&#xff0c;且具有闰年补偿等多种功能。 DS1302的性能特性&#xff1a; 实时时钟&#xff0c;可对秒、分、时、日、周、月以及带闰年补偿的年进行计数&#xff1b; 用于高速数据暂存的318位RAM&#xff1b; 最少引脚…

Redis --- 持久化、主从

一、Redis持久化 Redis有两种持久化方案&#xff1a; RDB持久化 AOF持久化 1.1、RDB持久化 RDB全称Redis Database Backup file&#xff08;Redis数据备份文件&#xff09;&#xff0c;也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中。当Redis实例故…

第 5 章 HBase 优化

5.1 RowKey 设计 一条数据的唯一标识就是 rowkey&#xff0c;那么这条数据存储于哪个分区&#xff0c;取决于 rowkey 处于 哪个一个预分区的区间内&#xff0c;设计 rowkey的主要目的 &#xff0c;就是让数据均匀的分布于所有的 region 中&#xff0c;在一定程度上防止数据倾斜…

年前无情被裁,我面试大厂的这3个月....

春招接近尾声&#xff0c;即将远去的“金三银四”今年也变成了“铜三铁四”。 大厂不断缩招&#xff0c;不容忽视的疫情影响&#xff0c;加上不断攀升的毕业生人数&#xff0c;各种需要应对的现实问题让整个求职季难上加难。 在这个异常残酷的求职季&#xff0c;很多人的困惑…

阿里系App抓包详细分析

InnerMtopInitTask OpenMtopInitTask ProductMtopInitTask 三个实现分别对应的instanceId为&#xff1a;OPEN、INNER、PRODUCT&#xff0c;咱们主要看InnerMtopInitTask这个实现&#xff0c;分析里面重要的初始化步骤&#xff0c;最后再使用Charles完成抓包。 IMtopInitTas…

发帖引蜘蛛:让你的网站在搜索引擎中的曝光率翻倍!

在当今的数字时代&#xff0c;SEO已成为提高网站曝光率和流量的重要手段。发帖引蜘蛛是一种有效的SEO技术&#xff0c;它可以让您的网站在搜索引擎中的曝光率翻倍&#xff0c;从而为您的业务带来更多的流量和潜在客户。 发帖引蜘蛛是一种简单易学的技术&#xff0c;它需要您在…

SPSS如何进行信度分析之案例实训?

文章目录 0.引言1.信度分析2.多维刻度分析 0.引言 因科研等多场景需要进行绘图处理&#xff0c;笔者对SPSS进行了学习&#xff0c;本文通过《SPSS统计分析从入门到精通》及其配套素材结合网上相关资料进行学习笔记总结&#xff0c;本文对信度分析进行阐述。 1.信度分析 &#…

【ROS】如何让ROS中节点实现数据交换Ⅰ--ROS话题通信

Halo&#xff0c;这里是Ppeua。平时主要更新C语言&#xff0c;C&#xff0c;数据结构算法…感兴趣就关注我吧&#xff01;你定不会失望。 目录 0.ROS文件系统及常用指令1.话题通信概念2.利用标准消息类型实现话题通信实现(python)2.1发布方实现2.2订阅方实现 3.利用自定义消息类…

[Dubbo] 重要接口与类

文章目录 1.dubbo的整体调用链路2.dubbo的源码整体设计3.重要接口和类 1.dubbo的整体调用链路 消费者通过Interface进行方法调用&#xff0c;统一交由消费者的Proxy处理&#xff08;Proxy通过ProxyFactory来进行代理对象的创建&#xff09; Proxy调用Filter模块&#xff0c;做…

搞懂 API ,API 分类全知道

API&#xff0c;即应用程序编程接口&#xff0c;是为了方便应用程序之间的数据和功能交互而设计的一些标准方法。API 的分类可以从多个维度进行&#xff0c;我会对 API 的分类维度进行简单的介绍。 根据使用方式的不同 通常情况下&#xff0c;API 可以分为两种使用方式&#…

【LeetCode】1143. 最长公共子序列

1.问题 给定两个字符串 text1 和 text2&#xff0c;返回这两个字符串的最长 公共子序列 的长度。如果不存在 公共子序列 &#xff0c;返回 0 。 一个字符串的 子序列 是指这样一个新的字符串&#xff1a;它是由原字符串在不改变字符的相对顺序的情况下删除某些字符&#xff0…

Springboot 项目搭建

目录 一、new project 二、pom.xml 三、配置 resources/application.yml 四、CodeGenerator 代码生成 五、在项目主启动类中&#xff0c;添加MapperScan注解 六、编写 Controller 七、选择application类&#xff0c; 点击运行 一、new project: 二、pom.xml <?xml …