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

news2024/7/7 17:15:55

本文将详细介绍如何在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.coloradmin.cn/o/1886583.html

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

相关文章

scikit-learn教程

scikit-learn&#xff08;通常简称为sklearn&#xff09;是Python中最受欢迎的机器学习库之一&#xff0c;它提供了各种监督和非监督学习算法的实现。下面是一个基本的教程&#xff0c;涵盖如何使用sklearn进行数据预处理、模型训练和评估。 1. 安装和导入包 首先确保安装了…

win10下安装PLSQL14连接Oracle数据库

问题背景 在使用Oracle开发过程中&#xff0c;经常会使用工具来连接数据库&#xff0c;方便查询、处理数据。其中有很多工具可以使用&#xff0c;比如dbeaver、plsql等。本文主要介绍在win10环境下&#xff0c;plsql14的安装步骤以及安装过程中遇到的一些问题。 安装步骤及问题…

JDBC操作流程

目录 简介 具体操作 1. 引入驱动包 1&#xff09;下载驱动包 2&#xff09;引入驱动包到项目中 2. 编写代码 1&#xff09;创建数据源 2&#xff09;建立连接 3&#xff09;构造 SQL 语句 4&#xff09;执行 SQL 语句 5&#xff09;释放资源 总结 简介 JDBC 就是使…

2024年工程项目管理者的软件指南:11款必试进度管理工具

本文将分享11个值得关注的工程项目进度管理软件&#xff1a;Worktile、Fieldwire、Procore、Buildxact、InEight、Contractor Foreman、Housecall Pro、ClickUp、RedTeam Go、Visual Planning、B2W Schedule。 在竞争激烈的建筑行业&#xff0c;工程项目的进度管理是项目成功的…

rocketmq实现多数据源配置

rocketmq实现多数据源配置 背景&#xff1a;一 添加ExtRocketMQTemplateConfiguration配置类二 添加非标mq的配置参数三 非标准RocketMQTemplate 背景&#xff1a; 在实际项目中我们可能会遇到在springboot项目中使用多个mq数据源&#xff0c;那我们该如何配置呢&#xff1f; …

[DataWhale大模型应用开发]学习笔记1-尝试搭建向量数据库

1.词向量 1.定义 词向量&#xff08;Word Vector&#xff09;是将单词表示为向量形式的技术&#xff0c;是自然语言处理&#xff08;NLP&#xff09;中的一种常用方法。通过将单词转化为向量&#xff0c;计算机能够更好地理解和处理语言。简单来说&#xff0c;词向量就是将单…

golang结合neo4j实现权限功能设计

neo4j 是非关系型数据库之图形数据库&#xff0c;这里不再赘述。 传统关系数据库基于rbac实现权限, user ---- role ------permission,加上中间表共5张表。 如果再添上部门的概念&#xff1a;用户属于部门&#xff0c;部门拥有 角色&#xff0c;则又多了一层&#xff1a; user-…

vulnhub靶场ai-web 2.0

1 信息收集 1.1 主机发现 arp-scan -l 主机地址为192.168.1.4 1.2 服务端口扫描 nmap -sS -sV -A -T5 -p- 192.168.1.4 开放22&#xff0c;80端口 2 访问服务 2.1 80端口访问 http://192.168.1.4:80/ 先尝试admin等其他常见用户名登录无果 然后点击signup发现这是一个注…

Codeforces Round 346 (Div. 2) E. New Reform 题解 并查集

New Reform 题目描述 Berland has n n n cities connected by m m m bidirectional roads. No road connects a city to itself, and each pair of cities is connected by no more than one road. It is not guaranteed that you can get from any city to any other one,…

如何养成爱自己的习惯:吸引世间美好,改变命运

在这个快节奏、高压力的时代&#xff0c;我们常常被各种事务所困扰&#xff0c;内心难以得到真正的宁静。然而&#xff0c;古老的智慧告诉我们&#xff0c;“静”是宇宙万物的根源&#xff0c;是生命恢复的根本。本文将探讨如何养成“静”的习惯&#xff0c;从而吸引世间美好&a…

Apache POI、EasyPoi、EasyExcel

&#xff08;一&#xff09;Apache PoI 使用 &#xff08;二&#xff09;EasyPoi使用 &#xff08;三&#xff09;EasyExcel使用 官方文档&#xff1a; 写Excel | Easy Excel 官网 写 使用注解在字段上进行标识 使用最简单的方法二即可 /*** 最简单的写* <p>* 1. 创建…

入门PHP就来我这(纯干货)04

~~~~ 有胆量你就来跟着路老师卷起来&#xff01; -- 纯干货&#xff0c;技术知识分享 ~~~~ 路老师给大家分享PHP语言的知识了&#xff0c;旨在想让大家入门PHP&#xff0c;并深入了解PHP语言。 我们接着《想入门PHP就来我这&#xff08;纯干货&#xff09;03》继续往下学习&am…

忘记家里的wifi密码用iPhone苹果手机怎么找回?

忘记家里的wifi密码用iPhone苹果手机怎么找回&#xff1f; 1、打开iPhone苹果手机上的设置&#xff1b; 2、在iPhone苹果手机设置里找到并进入无线局域网&#xff1b; 3、选择要找回密码的wifi&#xff0c;且已连接&#xff0c;并点击后面的更多进入&#xff1b; 4、进入无线局…

Excel分组求和

目录 1 参考文章2 UNIQUE函数分组3 SUMIF函数分组求和 1 参考文章 1.整体思路&#xff1a;https://blog.csdn.net/Alice_loong/article/details/135580130 2.UNIQUE函数&#xff1a;https://mp.weixin.qq.com/s?__bizMzI3OTcwNDE3OQ&mid2247487044&idx1&sna28108…

浅谈Web性能测试(原创)

一、性能测试不是什么高技术的活&#xff1a; 说到性能测试&#xff0c;很多工作时间较短的新同事或者应届生就很害怕。 为什么害怕&#xff0c;因为感觉无从下手&#xff0c;不知道该做什么、怎么做、做到什么程度&#xff1f; 一听性能测试首先想到的是各种专业的性能测试…

Echarts-柱状图

1.案例1 1.1代码 option = {textStyle: {color: #fff // 标题文字颜色为白色},tooltip: {trigger: axis,axisPointer: {type: shadow,},},legend: {textStyle: {color: white}},grid: {top: 15%,left: 4%,right: 4%,bottom: 7%,containLabel: true},xAxis:{type: category,da…

分文件编译(简单学生系统)

定义学生基本信息 ①输出所有学生信息 ②删除某个学生后&#xff0c;输出所有学生信息 ③修改某个学生信息后&#xff0c;输出所有学生信息 ④查找某个学生的信息 main.c #include"k11*.h" int main(int argc, const char *argv[]) {struct student p[4]{{"…

ShareX:不仅仅是截图工具

名人说&#xff1a;莫道谗言如浪深&#xff0c;莫言迁客似沙沉。 ——刘禹锡《浪淘沙》 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、软件介绍1、ShareX2、核心功能 二、下载安装1、下载2、安装 三、使用方法…

CentOS7.9下yum升级Apache HTTP Server2.4.6到2.4.60

CentOS7.9系统默认的Apache版本 在CentOS7.9上&#xff0c;如果使用yum安装Apache HTTP Server是最多到2.4.6版本的&#xff0c;这是因为el7下官方仓库的最高版本就是2.4.6&#xff0c;证据如下&#xff1a; $ yum info httpd ...... Installed Packages Name : httpd…

虚拟纪念展馆建设的重大意义:重新定义纪念活动的未来

一、什么是虚拟纪念展馆&#xff1f; 虚拟纪念展馆是一种利用3D、VR等技术在线展示历史事件、人物或文化遗产的数字化空间。这些展馆通过虚拟现实、增强现实和3D建模等技术手段&#xff0c;创建出身临其境的体验&#xff0c;使参观者可以在互联网上以互动方式探索和学习。 二、…