QT实现连接MySQL数据库以及查询等操作

news2024/11/25 9:37:37

QT实现连接数据库以及查询等操作

目录

  • QT实现连接数据库以及查询等操作
    • 实现效果
    • 建立数据库
    • 代码实现
      • 文件结构
      • 连接数据库
    • 所用类及其函数解释
    • 源代码
    • 后面的话

实现效果

在这里插入图片描述
功能包含数据库的增删改查和界面的显示,因为没有用.ui文件所以控件的位置都是手动设置的,写的有点费劲

建立数据库

首先打开Navicat,新建一个名字为bak_db的数据库,然后新建查询导入下面的sql语句:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for users
-- ----------------------------
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `password` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `permission` int(2) NOT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `username`(`username`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 40 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = DYNAMIC;

-- ----------------------------
-- Records of users
-- ----------------------------
INSERT INTO `users` VALUES (1, 'admin', '123456', 1);
INSERT INTO `users` VALUES (32, 'xfgc', 'dfhgrj', 2);
INSERT INTO `users` VALUES (39, '123', '456', 1);

SET FOREIGN_KEY_CHECKS = 1;

然后刷新显示表已经创建好了,接下来就开始进行操作了:

代码实现

文件结构

在这里插入图片描述
源码在我的github上,感兴趣的话可以下载运行试一下欢迎fork和star
运行不成功的可能是MySQL数据库的动态库没有导入,可以看一下这篇文章

连接数据库

首先是使用QSqlDatabase来创建数据库对象,使用

QSqlDatabase db=QSqlDatabase::addDatabase("QMYSQL");

后设置端口号、数据库地址、用户名、密码、数据库名

    db.setPort(3306);
    db.setHostName(hostname);//localhost
    db.setPassword(sqlpasswd);//数据库密码
    db.setUserName(sqlname);//数据库登录名
    db.setDatabaseName(dbname);//数据库的名字 我用的上面的数据库为bak_db

执行项目中的conn()函数就可以发现数据库连接成功了
关于从数据库中读取出来的信息,数据先存在二维数组中,后遍历二维数组放到QTableWidget中

void Mysql::flush_data(QVector<QVector<QString>>&userinfo)
{
    table->clear();
    if(!userinfo.size())return;
    table->setRowCount(userinfo.size());
    table->setColumnCount(4);
    for(int i=0;i<userinfo.size();i++)
    {
        for(int j=0;j<userinfo[0].size();j++)
        {
            table->setItem(i,j,new QTableWidgetItem(userinfo[i][j]));
        }
    }
     table->setHorizontalHeaderLabels({"id","用户名","密码","权限"});
}

bool Mysql::adduserinfo(QString user, QString passwd, QString per)
{
    QSqlQuery query(db);
    query.prepare("insert into users(username,password,permission) values(:user,:passwd,:per);");
    query.bindValue(":user",user);
    query.bindValue(":passwd",passwd);
    query.bindValue(":per",per);
    if(query.exec())
    {
        findall();
        return true;
    }
    return false;
}

按姓名删除


bool Mysql::del_byname(QString name)
{
    QSqlQuery query(db);
    query.prepare("delete from users WHERE  username=:user;");
    query.bindValue(":user",name);
    if(query.exec())
    {
        findall();
        return true;
    }
    return false;
}

按权限删除

bool Mysql::del_bypermission(QString permissionn)
{
    QSqlQuery query(db);
    query.prepare("delete from users WHERE  permission=:permission");
    query.bindValue(":permission",permissionn);
    if(query.exec())
    {
        findall();
        return true;
    }
    return false;
}

按名字查询

bool Mysql::updateuserinfo(QString user, QString passwd, QString per)
{
    QSqlQuery query(db);
    query.prepare("UPDATE users SET username=:user, password=:passwd ,permission=:per WHERE  username=:user;");
    query.bindValue(":user",user);
    query.bindValue(":passwd",passwd);
    query.bindValue(":per",per);
    if(query.exec())
    {
        findall();
        return true;
    }
    return false;
}


查询表中所有数据

void Mysql::findall()
{
    userinfo.clear();
    QSqlQuery query(db);
    query.prepare("select * from users;");
    if(query.exec())
    {
         while (query.next()) {
             QVector<QString>rec;
             for(int i=0;i<query.record().count();i++)
             {
                 rec.push_back(query.record().value(i).toString());
             }
             userinfo.push_back(rec);
         }
    }
}

按名字查询

bool Mysql::find_byname(QString name)
{
    userinfo.clear();
    QSqlQuery query(db);
        query.prepare("select * from users where username=:name;");
        query.bindValue(":name",name);
        if(query.exec())
        {
             while (query.next()) {
                 QVector<QString>rec;
                 rec.push_back(query.record().value("id").toString());
                 rec.push_back(query.record().value("username").toString());
                 rec.push_back(query.record().value("password").toString());
                 rec.push_back(query.record().value("permission").toString());

                 userinfo.push_back(rec);
             }
             return true;
        }
            return false;
}

按权限查询

bool Mysql::find_bypermission(QString permissionn)
{
    userinfo.clear();
    QSqlQuery query(db);
        query.prepare("select * from users where permission=:permission;");
        query.bindValue(":permission",permissionn);
        if(query.exec())
        {
             while (query.next()) {
                 QVector<QString>rec;
                 rec.push_back(query.record().value("id").toString());
                 rec.push_back(query.record().value("username").toString());
                 rec.push_back(query.record().value("password").toString());
                 rec.push_back(query.record().value("permission").toString());
                 userinfo.push_back(rec);
             }
             return true;
        }
        return false;
}

所用类及其函数解释

所用的类:

类名作用解释
QSqlDatabase用于管理和操作数据库连接的类QSqlDatabase类提供了与数据库建立连接、执行查询和事务处理相关的功能。
QTableWidget用于显示和编辑二维表格数据的控件QTableWidget类是Qt中用于展示和编辑二维表格数据的控件,允许用户直接在表格中进行修改、选择和排序。
QVector动态数组容器类,用于存储任意类型的数据QVector类是Qt中的一个动态数组容器,可以存储和操作各种类型的数据,支持自动内存管理和高效的插入、删除操作。
QSqlQuery用于执行SQL查询语句并处理结果的类QSqlQuery类提供了执行SQL查询语句、处理结果集以及绑定参数等功能,可以方便地进行数据库的查询和数据操作。
QRecord代表数据库结果集中的一行数据的类QRecord类用于代表数据库查询结果集中的一行数据,可以通过字段名或索引来访问和操作每个字段的值。

在项目中用到的函数的解释:

函数名返回值参数作用
QSqlDatabase ::setPort()voidint设置数据库连接的端口号
QSqlDatabase :: setHostName()voidQString设置数据库连接的主机名
QSqlDatabase ::setPassword()voidQString设置数据库连接的密码
QSqlDatabase ::setUserName()voidQString设置数据库连接的用户名
QSqlDatabase ::setDatabaseName()voidQString设置数据库连接的数据库名
QTableWidget::clear()void清除QTableWidget中的所有表项
QVector::clear()void清除QVector中的所有元素
QSqlQuery::prepare()boolQString准备SQL查询语句
QSqlQuery::exec()bool执行SQL查询或执行上次准备的查询语句
QSqlQuery::exec(bool)boolQString执行SQL查询语句,并将结果存储于内存以供后续访问
QSqlQuery::size()int获取查询结果的记录数
QSqlQuery::bindValue()voidQString, QVariant将参数绑定到SQL查询语句中的占位符
QRecord::count()int返回QRecord中的字段数
QRecord::value()QVariantint获取指定字段的值

源代码

mysql.pro

QT       += core gui sql

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    mysql.cpp

HEADERS += \
    mysql.h

FORMS +=

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

mysql.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include<QWidget>
#include<QSql>
#include<QSqlDatabase>
#include<QDebug>
#include<QSqlQuery>
#include<QSqlRecord>
#include <QSettings>
#include <QTableWidget>
#include <QPushButton>
#include <QLineEdit>
#include<QMessageBox>
QT_BEGIN_NAMESPACE
QT_END_NAMESPACE

class Mysql : public QWidget
{
    Q_OBJECT
public:
    Mysql(QWidget *parent = nullptr);
    ~Mysql();
    QSqlDatabase db=QSqlDatabase::addDatabase("QMYSQL");
    QString sqlname,hostname,sqlpasswd,dbname,sqlport;
    //查
    QPushButton* findname;
    QPushButton* findpermission;
    QLineEdit* inputinfo;
    //增
    QPushButton* addinfo;
    QLineEdit* user,*passwd,*permission;
    //改
    QPushButton* updateinfo;
    //删
    QPushButton* delname;
    QPushButton* delpermission;
    QLineEdit* inputdelinfo;
    QVector<QVector<QString>>userinfo;
    QTableWidget* table;
    QPushButton* all;
    //建立连接
    void conn();
    void init();
    //登录
    bool isAdmin;//判断是否是管理员
    bool isuser(QString username,QString password);
    void findall();//查看所有用户
    void flush_data(QVector<QVector<QString>>&userinfo);
    bool find_byname(QString name);
    bool find_bypermission(QString permission);
    bool adduserinfo(QString user,QString passwd,QString per);
    bool updateuserinfo(QString user,QString passwd,QString per);
    bool del_byname(QString name);
    bool del_bypermission(QString permissionn);
private:
};

#endif // MAINWINDOW_H

mysql.cpp

#include "mysql.h"

Mysql::Mysql(QWidget *parent)
    : QWidget(parent)
{
    conn();
    init();
}

Mysql::~Mysql()
{}

void Mysql::conn()
{
    sqlname="root";
    sqlpasswd="123456";
    hostname="localhost";
    dbname="bak_db";
    db.setPort(3306);
    db.setHostName(hostname);
    db.setPassword(sqlpasswd);
    db.setUserName(sqlname);
    db.setDatabaseName(dbname);
    if(db.open())
    {
        qDebug()<<"success!";
    }
    else {qDebug()<<"failed!";}
   // db.close();
}

void Mysql::init()
{
    this->setFixedSize(1000,1000);
    table=new QTableWidget(this);
    table->move(20,200);
    table->setFixedSize(500,500);
    QStringList headers;
    headers << "id" << "用户名" << "密码"<<"权限";
    table->setColumnCount(4);
    table->setHorizontalHeaderLabels(headers);

    inputinfo=new QLineEdit(this);
    inputinfo->setPlaceholderText("请输入姓名 / 权限");
    inputinfo->move(20,50);

    findname=new QPushButton("按姓名查询",this);
    findname->move(180,30);
    connect(findname,&QPushButton::clicked,[this](){
        QString name=inputinfo->text();
        if(find_byname(name))
        {
            flush_data(userinfo);
            userinfo.clear();
        }else  QMessageBox::critical(nullptr, "错误", "something wrong!", QMessageBox::Retry);
    });

     findpermission=new QPushButton("按权限查询",this);
     findpermission->move(180,70);
     connect(findpermission,&QPushButton::clicked,[this](){
         QString name=inputinfo->text();
         if(find_bypermission(name))
         {
             flush_data(userinfo);
             userinfo.clear();
         }
        else QMessageBox::critical(nullptr, "错误", "something wrong!", QMessageBox::Retry);
     });

     inputdelinfo=new QLineEdit(this);
     inputdelinfo->setPlaceholderText("请输入姓名 / 权限");
     inputdelinfo->move(280,50);

     delname=new QPushButton("按姓名删除",this);
     delname->move(440,30);
     connect(delname,&QPushButton::clicked,[this](){
         QString name=inputinfo->text();
         if(del_byname(name))
         {
             flush_data(userinfo);
             userinfo.clear();
         }else  QMessageBox::critical(nullptr, "错误", "something wrong!", QMessageBox::Retry);
     });

     delpermission=new QPushButton("按权限删除",this);
     delpermission->move(440,70);
     connect(delpermission,&QPushButton::clicked,[this](){
         QString name=inputinfo->text();
         if(del_bypermission(name))
         {
             flush_data(userinfo);
             userinfo.clear();
         }else  QMessageBox::critical(nullptr, "错误", "something wrong!", QMessageBox::Retry);
     });

     addinfo=new QPushButton("添加信息",this);
     addinfo->move(440,100);
     connect(addinfo,&QPushButton::clicked,[this](){
         if(adduserinfo(user->text(),passwd->text(),permission->text()))
         {
             flush_data(userinfo);
         }
     });

     updateinfo=new QPushButton("修改信息",this);
     updateinfo->move(440,130);
     connect(updateinfo,&QPushButton::clicked,[this](){
         if(updateuserinfo(user->text(),passwd->text(),permission->text()))
         {
             flush_data(userinfo);
         }
     });
     
     user=new QLineEdit(this);
     user->move(20,120);
     user->setPlaceholderText("请输入用户名");

     passwd=new QLineEdit(this);
     passwd->move(160,120);
     passwd->setPlaceholderText("请输入密码");

     permission=new QLineEdit(this);
     permission->move(300,120);
     permission->setPlaceholderText("请输入权限(1/2)");

     all=new QPushButton("查看所有信息",this);
     all->move(20,160);
     connect(all,&QPushButton::clicked,[this](){
         findall();
         flush_data(userinfo);
     });
    findall();
    flush_data(userinfo);
}

bool Mysql::isuser(QString username, QString password)
{
    QSqlQuery query1(db),query2(db);
    query1.prepare("select * from  users where username=:username "
                   "and password=:password and permission=1;");//查询是否为管理员
    query1.bindValue(":username",username);
    query1.bindValue(":password",password);

    query2.prepare("select * from  users where username=:username,"
                  "and password=:password and permission=2;");//查询是否为普通职员
    query2.bindValue(":username",username);
    query2.bindValue(":password",password);

    if (query1.exec()) {
        isAdmin=true;
        qDebug()<<"管理员登陆成功";
        return true;
    }
    else if(query2.exec())
    {
        isAdmin=false;
        qDebug()<<"普通职员登陆成功";
        return true;
    }
    else
     {
        qDebug()<<"用户名或密码错误!";
    }
    return false;
}

void Mysql::flush_data(QVector<QVector<QString>>&userinfo)
{
    table->clear();
    if(!userinfo.size())return;
    table->setRowCount(userinfo.size());
    table->setColumnCount(4);
    for(int i=0;i<userinfo.size();i++)
    {
        for(int j=0;j<userinfo[0].size();j++)
        {
            table->setItem(i,j,new QTableWidgetItem(userinfo[i][j]));
        }
    }
     table->setHorizontalHeaderLabels({"id","用户名","密码","权限"});
}

void Mysql::findall()
{
    userinfo.clear();
    QSqlQuery query(db);
    query.prepare("select * from users;");
    if(query.exec())
    {
         while (query.next()) {
             QVector<QString>rec;
             for(int i=0;i<query.record().count();i++)
             {
                 rec.push_back(query.record().value(i).toString());
             }
             userinfo.push_back(rec);
         }
    }
}

bool Mysql::find_byname(QString name)
{
    userinfo.clear();
    QSqlQuery query(db);
        query.prepare("select * from users where username=:name;");
        query.bindValue(":name",name);
        if(query.exec())
        {
             while (query.next()) {
                 QVector<QString>rec;
                 rec.push_back(query.record().value("id").toString());
                 rec.push_back(query.record().value("username").toString());
                 rec.push_back(query.record().value("password").toString());
                 rec.push_back(query.record().value("permission").toString());

                 userinfo.push_back(rec);
             }
             return true;
        }
            return false;
}

bool Mysql::find_bypermission(QString permissionn)
{
    userinfo.clear();
    QSqlQuery query(db);
        query.prepare("select * from users where permission=:permission;");
        query.bindValue(":permission",permissionn);
        if(query.exec())
        {
             while (query.next()) {
                 QVector<QString>rec;
                 rec.push_back(query.record().value("id").toString());
                 rec.push_back(query.record().value("username").toString());
                 rec.push_back(query.record().value("password").toString());
                 rec.push_back(query.record().value("permission").toString());
                 userinfo.push_back(rec);
             }
             return true;
        }
        return false;
}

bool Mysql::adduserinfo(QString user, QString passwd, QString per)
{
    QSqlQuery query(db);
    query.prepare("insert into users(username,password,permission) values(:user,:passwd,:per);");
    query.bindValue(":user",user);
    query.bindValue(":passwd",passwd);
    query.bindValue(":per",per);
    if(query.exec())
    {
        findall();
        return true;
    }
    return false;
}

bool Mysql::updateuserinfo(QString user, QString passwd, QString per)
{
    QSqlQuery query(db);
    query.prepare("UPDATE users SET username=:user, password=:passwd ,permission=:per WHERE  username=:user;");
    query.bindValue(":user",user);
    query.bindValue(":passwd",passwd);
    query.bindValue(":per",per);
    if(query.exec())
    {
        findall();
        return true;
    }
    return false;
}

bool Mysql::del_byname(QString name)
{
    QSqlQuery query(db);
    query.prepare("delete from users WHERE  username=:user;");
    query.bindValue(":user",name);
    if(query.exec())
    {
        findall();
        return true;
    }
    return false;
}

bool Mysql::del_bypermission(QString permissionn)
{
    QSqlQuery query(db);
    query.prepare("delete from users WHERE  permission=:permission");
    query.bindValue(":permission",permissionn);
    if(query.exec())
    {
        findall();
        return true;
    }
    return false;
}

main.cpp

#include "mysql.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Mysql w;
    w.show();
    return a.exec();
}

后面的话

写的时候发现每个表都需要使用数据类型(一维数组、哈希表、二维数组等)进行存储,而且基本上每涉及一个表就需要单独对这个表写增删改查之类的函数,这样造成了非常大的代码冗余,非常臃肿,但是目前我还没有想到什么办法能减少这种冗余简化代码,有一种方法是把数据库中的表对应的在qt中建立数据类,在类中建立对应表中表项的数据类型,之后查询到的数据对应的放到相应的类中,但是这样只是结构清晰了很多但是使用的内存空间还是同样大甚至更多。
其实也是因为自己这个月初要实现关于数据库的相关操作,然后就研究了一下,写完之后心血来潮想整理一下qt关于数据库的操作。感觉qt配置连接数据库简直比visualstudio简单太多了,甚至至今我还不能在vs上成功连接数据库,只能在vscode中使用cmakelists来连接数据库。

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

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

相关文章

【AI应用如何决策?如何研发出安全可信的AI应用?《Python可解释AI(XAI)实战》告诉你】

怎样才能有效地向A业务和利益相关者解释Al的决策?你需要仔细规划、设计和可视化。要解决的问题、模型以及变量之间的关系通常是微妙、出乎意料和复杂的。 《Python可解释AI&#xff08;XAI&#xff09;实战》通过几个精心设计的项目让你在实践中掌握众多XAI工具和方法&#x…

无涯教程-jQuery - triggerHandler( event, data )方法函数

triggerHandler(event&#xff0c;[data])方法触发元素(用于特定事件类型)上所有绑定的事件处理程序&#xff0c;而无需执行浏览器的默认操作&#xff0c;冒泡或实时事件。 triggerHandler( event, [data] ) - 语法 selector.triggerHandler( event, [data] ) 这是此方法使用…

【Matlab】基于粒子群优化算法优化BP神经网络的数据回归预测(Excel可直接替换数据)

【Matlab】基于粒子群优化算法优化 BP 神经网络的数据回归预测&#xff08;Excel可直接替换数据&#xff09; 1.模型原理2.数学公式3.文件结构4.Excel数据5.分块代码5.1 fun.m5.2 main.m 6.完整代码6.1 fun.m6.2 main.m 7.运行结果 1.模型原理 基于粒子群优化算法&#xff08;…

2、基于redis实现分布式锁

目录 2.1. 基本实现2.2. 防死锁2.3. 防误删2.4. redis中的lua脚本2.4.1 redis 并不能保证2.4.2 lua介绍 2.5. 使用lua保证删除原子性 2.1. 基本实现 借助于redis中的命令setnx(key, value)&#xff0c;key不存在就新增&#xff0c;存在就什么都不做。同时有多个客户端发送setn…

PhonewindowManager 使用详解

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: 一、Android 按键修改二、PhoneWindowManager 简介三、如何打开 或者 关闭 Navigation Bar四、如何长按Home 键启动Google Now五、如何长按实体Menu键进…

B. Vika and the Bridge

Example input 5 5 2 1 1 2 1 1 7 3 1 2 3 3 3 2 1 6 6 1 2 3 4 5 6 8 4 1 2 3 4 2 3 1 4 3 1 1 1 1 output 0 1 2 2 0 解析&#xff1a; 题意为每次只能踩相同颜色的木板&#xff0c;同时他有一次改变一块木板颜色的机会&#xff0c;问每种颜色的最大跨的步子长度中的最小…

Linux复习——基础知识

作者简介:一名云计算网络运维人员、每天分享网络与运维的技术与干货。 座右铭:低头赶路,敬事如仪 个人主页:网络豆的主页​​​​​ 1. 有关早期linux系统中 sysvin的init的7个级别描述正确的是( )[选择1项] A. init 1 关机状态 B. init 2 字符界面多用户模式 …

科技云报道:大模型的火烧到了AI服务器上

科技云报道原创。 大模型的纷争已经随着各大入局者公布产品后&#xff0c;热度逐渐退去&#xff0c;但是由大模型带来的产业链高频共振&#xff0c;已经传递了算力层。 表现最为激烈的&#xff0c;就是AI服务器市场。大模型带来的算力需求&#xff0c;直接引发了一波AI服务器…

算法(4)

字符串 给定一个数值的数组&#xff0c;要求组合最小的数值。 public String PrintMinNumber(Integer [] s) {if(snull) return null;String s1"";ArrayList<Integer> listnew ArrayList<Integer>(Arrays.asList(s)); // for(int i0;i<s.leng…

二维数组练习题-回形数

从键盘输入一个整数&#xff08;1~20&#xff09;&#xff0c;则以该数字为矩阵&#xff0c;将数字按照顺时针螺旋填入其中 package array;import java.util.Scanner;/*** author 苗晓强* date 2023/7/26 23:56* 回形数&#xff1a;* 从键盘输入一个整数&#xff08;1~20&…

从9G到0.3G,腾讯会议对他们的git库做了什么?

&#x1f449;导读 过去三年在线会议需求井喷&#xff0c;腾讯会议用户量骤增到3亿。快速迭代的背后&#xff0c;腾讯会议团队发现&#xff1a;业务保留了长达5年的历史数据&#xff0c;大量未进行 lfs 转换&#xff0c;新 clone 仓库本地空间占17.7G。本地磁盘面临严重告急&am…

FastSAM 论文解读

论文名称&#xff1a;Fast Segment Anything 论文地址&#xff1a;http://export.arxiv.org/pdf/2306.12156 代码地址&#xff1a;GitHub - CASIA-IVA-Lab/FastSAM: Fast Segment Anything 1. 关键内容 基于YOLOv8-seg实现了FastSAM&#xff0c;它比SAM快50倍&#xff0c;且…

数仓学习---15、数据仓库工作流调度

1、数据仓库工作流调度 1.1 调度工具部署 工具部署链接 1.2 新数据生成 1.2.1 用户行为日志 1、启动日志采集通道&#xff0c;包括Kafka、Flume等 &#xff08;1&#xff09;启动Zookeeper zk.sh start&#xff08;2&#xff09;启动Kafka kf.sh start&#xff08;3&…

【雕爷学编程】Arduino动手做(95)---GY9960手势传感器模块3

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

电容触摸屏(TP)的工艺结构

液晶显示屏(LCM),触摸屏(TP) “GG、GP、GF”这是结构分类&#xff0c;第一个字母表面材质&#xff08;又称为上层&#xff09;&#xff0c;第二个字母是触摸屏的材质&#xff08;又称为下层&#xff09;&#xff0c;两者贴合在一起。 G玻璃&#xff0c;FFILM&#xff0c;“”贴…

华为eNSP:路由引入

一、拓扑图 二、路由器的配置 1、配置路由器的IP AR1&#xff1a; [Huawei]int g0/0/0 [Huawei-GigabitEthernet0/0/0]ip add 1.1.1.1 24 [Huawei-GigabitEthernet0/0/0]qu AR2&#xff1a; [Huawei]int g0/0/0 [Huawei-GigabitEthernet0/0/0]ip add 1.1.1.2 24 [Huaw…

HarmonyOS学习路之方舟开发框架—学习ArkTS语言(状态管理 一)

状态管理概述 在前文的描述中&#xff0c;我们构建的页面多为静态界面。如果希望构建一个动态的、有交互的界面&#xff0c;就需要引入“状态”的概念。 图1 效果图 上面的示例中&#xff0c;用户与应用程序的交互触发了文本状态变更&#xff0c;状态变更引起了UI渲染&#x…

Blazor实战——Known框架多表增删改查

多表增删改查示例 本章介绍学习多张表增、删、改、查功能如何实现&#xff0c;下面以销货出库单作为示例&#xff0c;该业务栏位如下&#xff1a; 销货出库单栏位 销货单号、销货日期、状态、客户、备注 销货出库单明细栏位 商品编码、商品名称、规格型号、数量、单位、单价、…

详解rocketMq通信模块升级构想

本文从开发者的角度深入解析了基于netty的通信模块, 并通过简易扩展实现微服务化通信工具雏形, 适合于想要了解netty通信框架的使用案例, 想了解中间件通信模块设计, 以及微服务通信底层架构的同学。希望此文能给大家带来通信模块架构灵感。 概述 网络通信是很常见的需求&#…

065、故障处理之OMM_TiKV

TiKV Server OOM 对业务的影响 TiKV 上的请求失败造成异常退出region leader重新选举 raft group 开始选举新的 region leader新的region leader 上报信息给PD Server region cache频繁更新 在访问TiDB Server的region cache时&#xff0c;出现TiKV rpc相关报错后台自动进行Ba…