Qt中使用MySQL数据库详解,好用的模块类封装

本文将详细介绍如何在Qt应用程序中集成MySQL数据库,并封装实现好用的mysql数据库操作类。包括环境准备、连接数据库、执行查询及异常处理等关键步骤,同时包含mysql驱动的编译。分享给有需要的小伙伴,喜欢的可以点击收藏。

目录

环境准备

项目配置

简单使用

 简单示例

模块类封装

 如何使用

附qsqlmysql库的构建

前提条件

构建步骤

1. 查找Qt的安装路径和编译器

2. 设置环境变量

3. 获取MySQL开发库

4. 构建 qsqlmysql 插件

Windows:

Linux:

5. 将编译好的插件拷贝到合适的位置

注意事项

其他资源


Qt提供了QtSql模块来进行独立于平台的数据库操作,这里的“平台”既包括操作系统平台,也包括各个数据库平台。Qt使用一个QDatabase表示一个数据库连接。在底层,Qt使用不同的驱动程序来与不同的数据库API进行交互。

通常Qt只默认搭载了QSqlLite驱动程序,如果需要使用其他数据库,需要下载相应的数据库驱动,如mysql的为 qsqlmysql.dll,同时还需要mysql的客户端库libmysql.dll。

在连接数据库之前可以使用QSqlDatabase::drivers()查看本机Qt已经支持的数据库驱动。

环境准备

1.安装MySQL数据库:首先确保你的系统中安装了MySQL服务器,并创建好数据库和表结构。

2.安装Qt开发环境:安装Qt Creator及Qt库,确保包含SQL驱动模块。

注意:Qt默认并不包括MySQL驱动,需要手动构建。在QT安装目录(如Qt5.12.11\5.12.11\msvc2015_64\plugins\sqldrivers)里找,是否有qsqlmysql.dll和qsqlmysqld.dll.

如果没有则需要基于QT源码从新构建,构建好后把qsqlmysql.dll放入plugins\sqldrivers目录中。如果不存在该库,则程序执行会报QSqlDatabase: QMYSQL driver not loaded的错误。

如果要构建QMYSQL,需安装Qt源代码,并确保你的系统中安装了MySQL服务器或至少安装了MySQL Connector/C++,因为构建过程需要MySQL的头文件和库文件。

可以通过以下方式查看支持哪些驱动:

 qDebug()<<"support drivers:"<<QSqlDatabase::drivers();

3.安装MySQL的c/c++的Connector(MySQL客户端库):对于Qt 5.12及以上版本,MySQL驱动可能已内置,但若缺失,需下载MySQL Connector/C++并安装,确保Qt能找到libmysql动态库。(libmysql.dll动态库。链接:MySQL :: Download MySQL Connector/C (Archived Versions))

将压缩包解压,将lib文件夹下的libmysql.dll和libmysql.lib文件拷贝到Qt的安装目录的bin文件夹下即可。 

项目配置

在你的Qt项目文件(.pro)中添加如下行以启用SQL模块:

QT += sql

简单使用

编写代码连接数据库:

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>

void connectToDatabase() {
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("localhost");
    db.setDatabaseName("testdb");
    db.setUserName("root");
    db.setPassword("password");

    if (!db.open()) {
        qDebug() << "Failed to connect to database:" << db.lastError().text();
    } else {
        qDebug() << "Connected to database!";
    }
}
   

 简单示例

#include <QCoreApplication>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>

void connectToDatabase() {
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("localhost");
    db.setDatabaseName("testdb");
    db.setUserName("root");
    db.setPassword("password");

    if (!db.open()) {
        qDebug() << "Failed to connect to database:" << db.lastError().text();
    } else {
        qDebug() << "Connected to database!";
    }
}

bool createTable() {
    QSqlQuery query;
    bool success = query.exec("CREATE TABLE person (id INT PRIMARY KEY, name VARCHAR(40))");
    if (!success) {
        qDebug() << "Failed to create table:" << query.lastError().text();
    }
    return success;
}

bool insertRecord(int id, const QString &name) {
    QSqlQuery query;
    query.prepare("INSERT INTO person (id, name) VALUES (:id, :name)");
    query.bindValue(":id", id);
    query.bindValue(":name", name);
    bool success = query.exec();
    if (!success) {
        qDebug() << "Failed to insert record:" << query.lastError().text();
    }
    return success;
}

void queryRecords() {
    QSqlQuery query("SELECT id, name FROM person");
    while (query.next()) {
        int id = query.value(0).toInt();
        QString name = query.value(1).toString();
        qDebug() << id << name;
    }
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    connectToDatabase();
    createTable();
    insertRecord(1, "Alice");
    insertRecord(2, "Bob");
    queryRecords();

    return a.exec();
}

模块类封装

直接使用不太好用,这里做一个模块类封装,变得更好用啦,接口变得简单清晰。如果不封装,则原始是使用大概如下:

    QSqlQuery query(QSqlDatabase::database(connectionName, true));
    query.prepare("insert into test(name,age) values(:nameL,:ageL)");
    QStringList namelist;
    namelist<<"Tt"<<"Pp"<<"Kk";
    query.bindValue(":nameL",namelist);
    QVariantList agelist;
    agelist<<40<<50<<60;
    query.bindValue(":ageL",agelist);
    if(!query.execBatch()){
        qDebug()<<"数据插入失败: "<<query.lastError().text();
    }else{
        qDebug()<<"数据插入成功!";
    }

可以看到使用比较繁琐,封装后的模块代码如下: 

#include "mysqldb.h"
#include <QDebug>
#include <QUuid>

mysqlDb::mysqlDb() {
  qDebug()<<"support drivers:"<<QSqlDatabase::drivers();
}

mysqlDb::~mysqlDb() {
    disConnectSql();
}

//打开连接
bool mysqlDb::connectSql(const QString &dbName) {
    mdbName_= dbName;
    db = QSqlDatabase::database(connectionName);
    if(!db.isValid()) {
        QUuid qUuid = QUuid::createUuid();
        QString strUuid = qUuid.toString();
        connectionName = QString("mysql-%1").arg(strUuid);
        db = QSqlDatabase::addDatabase("QMYSQL",connectionName);
        db.setHostName(mhost_); //根据实际情况设置主机名
        db.setPort(mport_);
        db.setDatabaseName(dbName);
        db.setUserName(muser_); //根据实际情况设置用户名
        db.setPassword(mpwd_); //根据实际情况设置密码
        db.setConnectOptions("MYSQL_OPT_RECONNECT=1"); // 支持断线重连
        if (!db.open()) {
            qWarning("Failed to open database: %s", qPrintable(db.lastError().text()));
            return false;
        }
    }
    return true;
}
//打开连接
bool mysqlDb::connectSql(const QString &host, int port, const QString &dbName, const QString &userName, const QString &password) {
    mhost_= host;
    mport_= port;
    mdbName_= dbName;
    muser_= userName;
    mpwd_ = password;
    db = QSqlDatabase::database(connectionName);
    if(!db.isValid()) {
        QUuid qUuid = QUuid::createUuid();
        QString strUuid = qUuid.toString();
        connectionName = QString("mysql-%1").arg(strUuid);
        db = QSqlDatabase::addDatabase("QMYSQL",connectionName);
        db.setHostName(host); //根据实际情况设置主机名
        db.setPort(port);
        db.setDatabaseName(dbName);
        db.setUserName(userName); //根据实际情况设置用户名
        db.setPassword(password); //根据实际情况设置密码
        db.setConnectOptions("MYSQL_OPT_RECONNECT=1"); // 支持断线重连
        if (!db.open()) {
            qWarning("Failed to open database: %s", qPrintable(db.lastError().text()));
            return false;
        }
    }
    return true;
}

//关闭连接
bool mysqlDb::disConnectSql() {
    db = QSqlDatabase::database(connectionName);
    if(!db.isValid()) {
        return true;
    }
    db.close();
    QSqlDatabase::removeDatabase(connectionName);
    connectionName = "";
    return true;
}

//错误打印
void mysqlDb::errorSql(QString sql) {
    errorSqlText = sql;
    qCritical("%s", qPrintable(errorSqlText));
}

//获取错误的数据库语句
QString mysqlDb::getErrorSql() {
    if(connectionName.isEmpty()) {
        return "db not setting";
    }
    return errorSqlText;
}

void mysqlDb::setMdbName(const QString &mdbName)
{
    mdbName_ = mdbName;
}

void mysqlDb::setMpwd(const QString &mpwd)
{
    mpwd_ = mpwd;
}

void mysqlDb::setMuser(const QString &muser)
{
    muser_ = muser;
}

void mysqlDb::setMhost(const QString &mhost)
{
    mhost_ = mhost;
}

void mysqlDb::setMport(int mport)
{
    mport_ = mport;
}

//执行sql语句,不获取结果
bool mysqlDb::queryExec( QString queryStr) {
    if(connectionName.isEmpty()) {
        if(!connectSql(mhost_,mport_,mdbName_,muser_,mpwd_)) {
            return false;
        }
    }
    QSqlQuery query(QSqlDatabase::database(connectionName, true));
    if(!query.exec(queryStr)) {
        errorSql(queryStr);
        return false;
    }
    return true;
}

//执行sql语句,并获取结果
bool mysqlDb::queryExec( QString queryStr, QList<QHash<QString, QString>> &data) {
    data.clear();
    if(connectionName.isEmpty()) {
        if(!connectSql(mhost_,mport_,mdbName_,muser_,mpwd_)) {
            return false;
        }
    }
    QSqlQuery query(QSqlDatabase::database(connectionName, true));
    if(!query.exec(queryStr)) {
        errorSql(queryStr);
        return false;
    }
    QSqlRecord rec = query.record();
    while(query.next()) {
        QHash<QString, QString> rowData;
        for(int i = 0; i < rec.count(); i++) {
            QVariant::Type ty = query.value(i).type();
            if(QVariant::Type::Date == ty) {
                QDate temp = query.value(i).toDate();
                rowData[rec.fieldName(i)] = temp.toString("yyyy-MM-dd");
            } else if(QVariant::Type::Time == ty) {
                QTime temp = query.value(i).toTime();
                rowData[rec.fieldName(i)] = temp.toString("hh:mm:ss");
            } else if(QVariant::Type::DateTime == ty) {
                QDateTime temp = query.value(i).toDateTime();
                rowData[rec.fieldName(i)] = temp.toString("yyyy-MM-dd hh:mm:ss");
            } else {
                rowData[rec.fieldName(i)] = query.value(i).toString();
            }
        }
        data.append(rowData);
    }
    return true;
}

//获取数据
bool mysqlDb::getData(QString tableName, QHash<QString, QString> &data, QString sqlWhere) {
    data.clear();
    QList<QHash<QString, QString>> dataList;
    if(!getData(tableName, dataList, sqlWhere)) {
        return false;
    }
    if(dataList.count() > 0) {
        data = dataList[0];
    }
    return true;
}

//获取数据
bool mysqlDb::getData( QString tableName, QList<QHash<QString, QString>> &data, QString sqlWhere) {
    QString queryStr = "select * from " + tableName;
    if(!sqlWhere.isEmpty()) {
        queryStr += " " + sqlWhere;
    }
    return queryExec(queryStr, data);
}

//获取数据
bool mysqlDb::getData(QString tableName, QHash<QString, QString> columndata, QList<QHash<QString, QString>> &data, QString sqlWhere) {
    QString colunmStr;
    if(columndata.count() == 0) {
        colunmStr = "*";
    } else {
        QStringList keys = columndata.keys();
        for(auto key : keys) {
            QString column = QString("%1 AS %2").arg(key).arg(columndata[key]);
            if(!colunmStr.isEmpty()) {
                colunmStr += ",";
            }
            colunmStr += column;
        }
    }
    QString queryStr = QString("SELECT %1 FROM %2 %3").arg(colunmStr).arg(tableName).arg(sqlWhere);
    return queryExec(queryStr, data);
}

//增加
bool mysqlDb::addData(QString tableName, QHash<QString, QString> data) {
    if(data.isEmpty()) {
        return false;
    }
    QString queryStr = "INSERT INTO " + tableName + " ";
    QString fieldStr = "(", valueStr = "VALUES(";
    QHash<QString, QString>::iterator it;
    for(it = data.begin(); it != data.end(); ++it) {
        fieldStr += it.key() + ",";
        valueStr += "'" + it.value() + "',";
    }
    fieldStr = fieldStr.left(fieldStr.length() - 1);
    valueStr = valueStr.left(valueStr.length() - 1);
    fieldStr += ")";
    valueStr += ")";
    queryStr += fieldStr + " " + valueStr;
    return queryExec(queryStr);
}

//删除
bool mysqlDb::delData(QString tableName, QString sqlWhere) {
    QString queryStr = "DELETE FROM " + tableName;
    if(!sqlWhere.isEmpty()) {
        queryStr += " " + sqlWhere;
    }
    return queryExec(queryStr);
}

//修改
bool mysqlDb::updateData( QString tableName, QHash<QString, QString> data, QString sqlWhere) {
    QString queryStr = "UPDATE " + tableName + " ";
    QHash<QString, QString>::iterator it;
    QString setStr = "SET ";
    for(it = data.begin(); it != data.end(); ++it) {
        setStr += it.key() + "='" + it.value() + "'";
        setStr += ",";
    }
    setStr = setStr.left(setStr.length() - 1);
    queryStr += setStr;
    if(!sqlWhere.isEmpty()) {
        queryStr += " " + sqlWhere;
    }
    return queryExec(queryStr);
}

bool mysqlDb::transaction() {
    if(connectionName.isEmpty()) {
        return false;
    }
    return db.transaction();
}

bool mysqlDb::commit() {
    if(connectionName.isEmpty()) {
        return false;
    }
    return db.commit();
}
#ifndef MYSQLDB_H
#define MYSQLDB_H
 
#include <QDir>
#include <QDate>
#include <QDateTime>
#include <QFileInfo>
#include <QString>
#include <QTime>
#include <QSqlDatabase>
#include <QSqlRecord>
#include <QSqlQuery>
#include <QSqlError>
#include <QVariant>
 
class mysqlDb
{
public:
    mysqlDb();
    ~mysqlDb();
public:
    bool connectSql(const QString &dbName);//打开连接
    bool connectSql(const QString &host, int port, const QString &dbName, const QString &userName, const QString &password);//打开连接
    bool disConnectSql();//关闭连接
    bool queryExec(QString sqlStr);//执行sql语句,不获取结果
    bool queryExec(QString sqlStr,QList<QHash<QString,QString>> &data);//执行sql语句,并获取结果
    bool getData(QString tableName,QHash<QString,QString> &data,QString sqlWhere=""); //获取数据
    bool getData(QString table,QList<QHash<QString,QString>> &data,QString sqlWhere=""); //获取数据
    bool getData(QString tableName,QHash<QString,QString> columndata,QList<QHash<QString,QString>> &data,QString sqlWhere=""); //获取数据
    bool addData(QString tableName,QHash<QString,QString> data);//增加
    bool delData(QString tableName,QString sqlWhere);//删除
    bool updateData(QString tableName,QHash<QString,QString> data,QString sqlWhere="");//修改

    bool transaction();
    bool commit();
    QString getErrorSql();//获取错误的数据库语句

    void setMhost(const QString &mhost);
    void setMport(int mport);
    void setMdbName(const QString &mdbName);
    void setMuser(const QString &muser);
    void setMpwd(const QString &mpwd);

private:
    QSqlDatabase db;
    QString connectionName="";
    QString errorSqlText;//错误语句
    QString mdbName_="";
    QString mhost_ = "localhost";
    int mport_ = 3306;
    QString muser_="";
    QString mpwd_="";

private:
    void errorSql(QString sql);//错误打印
};
 
#endif // MYSQLDB_H
 

 如何使用

void MainWindow::on_btn_test_clicked()
{
 mysqlDb* db = new mysqlDb();
 db->setMhost("111.178.126.10");
 db->setMuser("xxxxxx");
 db->setMpwd("xxxxxx");
 bool ret = db->openSql("test");
 if(ret){
    qDebug("connect ok");

    //插入数据
    QHash<QString, QString> user;
    user.insert("name","yang");
    user.insert("age","30");
    ret = db->addData("user",user);
    if(ret){
          qDebug("insert ok");
    }else{
        qDebug("insert error");
    }

    //读取数据
    QList<QHash<QString, QString>> data;
    ret = db->getData("user",data,"");
    if(ret){
          qDebug("get ok");
          for(auto d:data){
              qDebug(d["user"].toStdString().c_str());
              qDebug(d["age"].toStdString().c_str());
          }
    }else{
        qDebug("get error");
    }

    //更新
    QHash<QString, QString> update;
    update.insert("age","35");
    ret = db->updateData("user",update,"where age = 30");
    if(ret){
          qDebug("updateData ok");
    }else{
        qDebug("updateData error");
    }

    //删除
    ret = db->delData("user","where age = 32");
    if(ret){
          qDebug("delete ok");
    }else{
        qDebug("delete error");
    }

 }else{
     qDebug("connect error");
 }
}

附qsqlmysql库的构建

如果已经有该库,以下步骤可忽略。该库位置在Qt5.xx\5.xx\msvc20xx_\plugins\sqldrivers

qsqlmysql库是Qt框架中用于连接MySQL数据库的一个插件库。它是Qt SQL模块的一部分,专门设计用于提供对MySQL数据库的支持。

前提条件

  1. 安装Qt:确保你已经安装了Qt和Qt Creator。
  2. 安装MySQL客户端库
    • Windows环境下,可以直接下载 MySQL C API 开发包 (MySQL Connector/C)。
    • Linux环境,可通过包管理器安装(例如 sudo apt-get install libmysqlclient-dev)。
    • macOS环境,可通过Homebrew安装(例如 brew install mysql-client)。
  3. 下载QT相应版本的源码,比如我的是Qt5.14.2。下载地址:https://download.qt.io/

构建步骤

1. 查找Qt的安装路径和编译器
  • 确认你的Qt安装路径。例如:C:\Qt\5.x.x\mingwxx_32
  • 确认你使用的编译器,如 MinGW 或 MSVC,以及其路径。
  • QT的源码不用全解压,只需要qtbase这个文件夹下的全部内容。
2. 设置环境变量
  • 将Qt的编译工具(如qmake)添加到系统的PATH变量中。
3. 获取MySQL开发库
  • 确保你已经下载并解压了 MySQL Connector/C 用于 Windows 系统;在Linux和macOS系统上安装相应的开发库会自动设置好的路径。
4. 构建 qsqlmysql 插件

使用Qtcreator打开D:\Qt\qtbase\src\plugins\sqldrivers\mysql\mysql.pro工程文件。

打开工程后,会报错:Cannot read qtsqldrivers-config.pri: No such file or directory

接下来需要对mysql.pro文件和它上一级的qsqldriverbase.pri文件做出修改:

修改qsqldriverbase.pri

QT  = core core-private sql-private

# For QMAKE_USE in the parent projects.
#注释到这个
#include($$shadowed($$PWD)/qtsqldrivers-config.pri)
#新增加这个
include(./configure.pri)

PLUGIN_TYPE = sqldrivers
load(qt_plugin)

DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII

修改 mysql.pro:

TARGET = qsqlmysql

HEADERS += $$PWD/qsql_mysql_p.h
SOURCES += $$PWD/qsql_mysql.cpp $$PWD/main.cpp

#注释到这个
#QMAKE_USE += mysql

OTHER_FILES += mysql.json

PLUGIN_CLASS_NAME = QMYSQLDriverPlugin
#以下为新增
#!!mysql的lib路径
LIBS += D:\Qt\mysql-connector-c-6.1.11-winx64/lib/libmysql.lib
#!!mysql的include路径
INCLUDEPATH += $$quote(D:\Qt\mysql-connector-c-6.1.11-winx64/include)
#!!mysql的include路径
DEPENDPATH += $$quote(D:\Qt\mysql-connector-c-6.1.11-winx64/include)

include(../qsqldriverbase.pri)

#!!设置编译好的qmysql.dll放置的目录
DESTDIR = ../mysql/mysqlDll
5. 将编译好的插件拷贝到合适的位置
  • 将编译得到的 qsqlmysql.dll(或 libqsqlmysql.so 或 libqsqlmysql.dylib)放到Qt的插件目录下。例如 C:\Qt\5.x.x\mingwxx_64\plugins\sqldrivers(Windows)或 /path/to/qt/plugins/sqldrivers(Linux和macOS)。

注意事项

  1. 版本匹配:请确保你的 MySQL 客户端库版本与 MySQL 服务器版本兼容,同时确保与 Qt 使用的编译器版本一致。
  2. 路径问题:在运行示例程序时,所有路径要使用绝对路径或将相关路径加入到环境变量中以确保 Qt 能够找到相应的库文件。
  3. 权限问题:在Linux和macOS环境下,可能需要使用sudo来执行某些命令以拥有足够的权限。

按照上述步骤,你应该能够成功构建并使用 qsqlmysql 插件来连接 MySQL 数据库。

最后,附上编译好的mysql驱动,含windows和mac版本的(5.14.2,5.15.2,6.5.3)

链接如下:

https://pan.baidu.com/s/1m15DbFuFTtXfEyqyOS2cew
提取码: 2o2s

其他资源

https://www.cnblogs.com/zhuchunlin/p/16485933.html

QT连接MYSQL(保姆级成功案例)_qt mysql-CSDN博客

QT学习之路——Qt QMySQL driver not loaded问题(笔记)_qsqldatabase: qmysql driver not loaded qsqldatabas-CSDN博客

MySQL :: Download MySQL Connector/C (Archived Versions)

QT加载mysql失败,重新构建mysql源文件_qt重新加载资源文件-CSDN博客

QT操作Mysql数据库_qt mysql-CSDN博客

https://www.cnblogs.com/flygreen/p/18029637

Qt连接mysql数据库_不能找到qtsqldrivers-config.pri-CSDN博客

Linux下Qt 5.15.2源码下载及编译_qt5 linux 源码下载-CSDN博客

qt creator mysql_qt creator with mysql-CSDN博客

编译qt5.15.2(mac/windows)的mysql驱动(附带编译好的文件)_macos编译qt5.15.2-CSDN博客

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySql Innodb锁机制

锁概述 undo log版本链 Read View机制实现的MVCC多版本并发控制&#xff0c;可以防止事务并发读写同一数据时出现的脏读不可重复读幻读问题。但除脏读不可重复读幻读问题外&#xff0c;并发读写同一数据还有脏写问题。就是当多个事务并发更新同一条数据时&#xff0c;此时就可…

【CT】LeetCode手撕—199. 二叉树的右视图

目录 题目1- 思路2- 实现⭐199. 二叉树的右视图——题解思路 3- ACM 实现 题目 原题连接&#xff1a;199. 二叉树的右视图 1- 思路 使用二叉树的层序遍历 2- 实现 ⭐199. 二叉树的右视图——题解思路 class Solution {public List<Integer> rightSideView(TreeNode ro…

Let‘s Encrypt 申请免费 SSL 证书(每隔60天自动更新证书)

文章目录 官网文档简介安装 Nginxacme.sh生成证书智能化生成证书 安装证书查看已安装证书更新证书 官网 https://letsencrypt.org/zh-cn/ 文档 https://letsencrypt.org/zh-cn/docs/ 简介 Let’s Encrypt 是一个非营利组织提供的免费SSL/TLS证书颁发机构&#xff0c;旨在促…

如何在 Windows 10 或 11 中恢复已删除的文件

您在 Windows PC 上找不到某个文件&#xff0c;并且您觉得可能已将其删除。我们都遇到过这种情况。但与其抱怨&#xff0c;不如尝试恢复它。假设您已经搜索过回收站&#xff0c;但一无所获&#xff0c;那么是时候求助于一个好的恢复工具了。 微软提供了自己的命令行恢复程序&a…

Vite: 插件流水线之核心编译能力

概述 Vite 在开发阶段实现了一个按需加载的服务器&#xff0c;每一个文件请求进来都会经历一系列的编译流程&#xff0c;然后 Vite 会将编译结果响应给浏览器。在生产环境下&#xff0c;Vite 同样会执行一系列编译过程&#xff0c;将编译结果交给 Rollup 进行模块打包这一系列…

Node端使用工作线程来解决日志开销-处理IO密集型任务

我们的BBF层很多时候会作为中间层处理后端到前端的数据&#xff0c;当然大部分时候都只是作为请求 / 响应的数据组装中心&#xff0c;但是有一个插件是怎么都绕不过去的&#xff1a;Log4js。 内部我们在Node层打印了很多日志。结果这周仔细分析了一下服务器处理请求到响应的中间…

excel数据大小显示竟然有最大限制,限制32,767,实际限制32759

Excel 单元格在显示数据时确实存在一些限制&#xff0c;这些限制主要与单元格的宽度和高度有关&#xff0c;而不是存储数据的大小。以下是一些主要的限制&#xff1a; 1. **列宽和行高**&#xff1a;Excel 单元格的显示大小取决于列宽和行高。如果单元格中的数据超出了设定的列…

C# Winform项目中简单使用Sqlite并在DataGridview中显示

1. SQLite概述 1.1 什么是 SQLite&#xff1f; SQLite是一个进程内的库&#xff0c;实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库&#xff0c;这意味着与其他数据库不一样&#xff0c;您不需要在系统中配置。 1.2 为什么要用 …

vmware虚拟机安装openEuler

一、openEuler简介 openEuler是一款开源操作系统。当前openEuler内核源于Linux&#xff0c;支持鲲鹏及其它多种处理器&#xff0c;能够充分释放计算芯片的潜能&#xff0c;是由全球开源贡献者构建的高效、稳定、安全的开源操作系统&#xff0c;适用于数据库、大数据、云计算、…

游戏AI的创造思路-技术基础-自然语言处理

自然语言处理-可以对游戏AI特别是RPG类、语言类游戏进行“附魔”&#xff0c;开发出“随机应变”和你聊天的“女友”、“队友”或者是根据你定义的文本库来用接近自然语言的生成“语言”&#xff0c;推动游戏情景在受控范围内前进 目录 1. 自然语言处理定义 2. 发展历史 3. …

k8s部署单节点redis

一、configmap # cat redis-configmap.yaml apiVersion: v1 kind: ConfigMap metadata:name: redis-single-confignamespace: redis data:redis.conf: |daemonize nobind 0.0.0.0port 6379tcp-backlog 511timeout 0tcp-keepalive 300pidfile /data/redis-server.pidlogfile /d…

高考服务系统

摘 要 每年有大批考生在进行填写高考志愿时并不很清楚自己的高考分数适合那些高校以及专业。高考考生面临着未被高校录取&#xff0c;被调剂专业&#xff0c;甚至可能复读的问题。若能让考生轻松查询到高校录取、高校专业、高校招生等相关信息&#xff0c;能减少很大一部分考生…

《后端程序猿 · Caffeine 本地缓存》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻一周&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…

SolrCloud Autoscaling 自动添加副本

SolrCloud Autoscaling 自动添加副本 前言 问题描述 起因是这样的&#xff0c;我在本地调试 Solr 源码&#xff08;版本 7.7.3&#xff09;&#xff0c;用 IDEA 以 solrcloud 方式启动了 2 个 Solr 服务&#xff0c;如下所示&#xff1a; 上图的启动参数 VM Options 如下&am…

QT控制comboBox切换方法

目录 1. 效果2. 操作 1. 效果 如下图&#xff1a; 点击全切换雨天模式按钮 则 comboBox 文本显示为 “雨天模式”点击全切换正常模式按钮 则 comboBox 文本显示为 “雨天模式” 切换到 雨天模式 切换到 正常模式 2. 操作 使用 “setCurrentIndex” 方法&#xff0c;切换 combo…

vmware虚拟机增加磁盘容量

概述 当初始分配给虚拟机的磁盘空间不够时&#xff0c;需要从外部的主系统增加配给。 具体操作分为两步&#xff1a;一&#xff1a;通过虚拟机界面添加分配的磁盘配给&#xff1b;二&#xff1a;将新分配的配给给使用起来。 操作 添加磁盘配给 在虚拟机内部添加新分配的配给…

安装Intel Realsense D435i驱动与ROS包报错

1.下载安装realsense SDK 1.1 安装依赖 sudo apt install libudev-dev pkg-config libgtk-3-dev sudo apt install libusb-1.0-0-dev pkg-config sudo apt install libglfw3-dev sudo apt install libssl-dev1.2 权限 cd librealsense/ sudo cp config/99-realsense-libusb.…

独享代理VS共享代理,新手选择攻略

随着互联网的广泛普及和应用&#xff0c;涉及网络隐私、数据安全和网络访问控制的问题变得越来越重要。代理服务器作为一种常见的网络工具&#xff0c;可以在跨境电商、海外社媒、SEO投放、网页抓取等领域发挥作用&#xff0c;实现匿名访问并加强网络安全。在代理服务器类别中&…

GoLand 2024 for Mac GO语言集成开发工具环境

Mac分享吧 文章目录 效果一、下载软件二、开始安装1、双击运行软件&#xff08;适合自己的M芯片版或Intel芯片版&#xff09;&#xff0c;将其从左侧拖入右侧文件夹中&#xff0c;等待安装完毕2、应用程序显示软件图标&#xff0c;表示安装成功3、打开访达&#xff0c;点击【文…

哪个牌子的充电宝牌子便宜好用?2024年性价比高充电宝排行榜!

在 2024 年&#xff0c;充电宝市场依旧琳琅满目&#xff0c;让人眼花缭乱。大家都在寻找那个既便宜又好用的充电宝&#xff0c;可面对众多品牌和产品&#xff0c;常常感到无从下手。别担心&#xff01;经过深入的市场调研和实际使用体验&#xff0c;我们为您精心整理出了 2024 …