当前位置: 首页 > news >正文

QT编程之数据库开发

一、架构层次

  1. 用户接口层

    • QSqlQueryModel‌:管理SQL查询结果,提供表格数据模型用于展示‌
    • QSqlTableModel‌:支持直接操作数据库表(增删改查)‌
    • QSqlRelationalTableModel‌:支持带外键关联的复杂表操作‌
  2. SQL接口层

    • QSqlDatabase‌:创建和管理数据库连接‌
    • QSqlQuery‌:执行SQL语句和遍历结果集‌
    • QSqlRecord‌:封装数据库记录操作(字段管理)‌
  3. 驱动层
    支持多种数据库驱动插件(QSQLITE、QMYSQL等),通过抽象接口实现跨数据库兼容‌

二、Qt支持的数据库类型

  1. SQLite
    Qt内置支持SQLite数据库,无需额外安装驱动,适合嵌入式和小型应用‌。
  2. MySQL/Oracle/SQL Server
    需安装对应数据库驱动模块(如QMYSQL、QODBC等),支持通过ODBC或原生驱动连接‌。
  3. 其他数据库
    包括PostgreSQL等,需通过QSqlDatabase::drivers()查看当前支持的驱动列表‌。

三、数据库连接步骤

  1. 添加SQL模块
    在项目配置文件(.pro)中添加:QT += sql
  2. 加载驱动并创建连接
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");  // SQLite示例
    db.setDatabaseName("my.db");  // 设置数据库文件路径
    if (!db.open()) {qDebug() << "连接失败:" << db.lastError().text();
    }
  3. 多数据库连接
    通过指定不同连接名实现多个数据库同时操作:
    QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE", "connection1");
    QSqlDatabase db2 = QSqlDatabase::addDatabase("QMYSQL", "connection2");

四、基本数据库操作

  1. 执行SQL语句
    使用QSqlQuery执行增删改查操作:

    QSqlQuery query;
    query.exec("CREATE TABLE user (id INT PRIMARY KEY, name TEXT)");  // 创建表
    query.exec("INSERT INTO user VALUES (1, 'Alice')");               // 插入数据
  2. 查询数据

    if (query.exec("SELECT * FROM user")) {while (query.next()) {int id = query.value("id").toInt();QString name = query.value("name").toString();}
    }
  3. 预处理语句(防SQL注入)

    query.prepare("INSERT INTO user (id, name) VALUES (:id, :name)");
    query.bindValue(":id", 2);
    query.bindValue(":name", "Bob");
    query.exec();

五、高级功能

  1. 事务处理

    db.transaction();
    // 执行多条SQL操作
    if (操作成功) db.commit();
    else db.rollback();
  2. 模型-视图架构
    使用QSqlTableModelQSqlQueryModel实现数据与UI组件的绑定:

    QSqlTableModel *model = new QSqlTableModel(this);
    model->setTable("user");
    model->select();
    tableView->setModel(model);

六、注意事项

  1. 驱动兼容性
    确保目标平台已安装对应数据库驱动(如Windows需libmysql.dll)‌。
  2. 错误处理
    通过QSqlError捕获并处理数据库操作中的异常‌。
  3. 性能优化
    批量操作建议使用事务,避免频繁打开/关闭连接‌。
  4. 中文乱码
    在连接字符串中添加 ;Charset=UTF8;,确保数据库字段使用 NVARCHAR。

七、MS SQL SERVER

在Qt中操作Microsoft SQL Server,你可以使用多种方法,包括使用ODBC(Open Database Connectivity)连接,或者使用专门的库如QODBC或QSqlServer(如果你使用的是Qt 5或更高版本,并且有对应的插件)。以下是两种常见的方法:

方法1:使用QODBC

1)确保你的系统安装了ODBC驱动:
对于Windows,通常SQL Server ODBC驱动已经预装。你可以在ODBC数据源管理器中检查这一点。
2)在Qt项目中配置ODBC连接:
如果你使用的是Qt 5或更高版本,并且你的系统上安装了SQL Server ODBC驱动,你可以直接使用QODBC驱动。
3)连接数据库代码:

#include <QSqlDatabase>
#include <QDebug>int main() {QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");db.setHostName("你的服务器名"); // 例如 localhost 或 IP 地址db.setDatabaseName("你的数据库名");db.setUserName("你的用户名");db.setPassword("你的密码");if (!db.open()) {qDebug() << "无法打开数据库:" << db.lastError().text();return -1;}qDebug() << "数据库连接成功!";// 执行查询等操作...return 0;
}
方法2:使用QSqlServer

如果你使用的是Qt 5.7或更高版本,可以直接使用QSqlServer驱动,而无需ODBC。
1)确保你的Qt版本支持QSqlServer:
2)连接数据库代码:

#include <QSqlDatabase>
#include <QDebug>int main() {QSqlDatabase db = QSqlDatabase::addDatabase("QSQLSERVER");db.setHostName("你的服务器名"); // 例如 localhost 或 IP 地址 (对于本地服务器可以留空)db.setDatabaseName("你的数据库名"); // 不需要加前缀例如"数据库名"而不是"Driver={SQL Server};Server=服务器名;Database=数据库名;"db.setUserName("你的用户名");db.setPassword("你的密码");if (!db.open()) {qDebug() << "无法打开数据库:" << db.lastError().text();return -1;}qDebug() << "数据库连接成功!";// 执行查询等操作...return 0;
}

完整实例代码:

1)数据库连接类 DatabaseManager.h

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>class DatabaseManager {
public:static bool connect() {QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");QString connectionString = "DRIVER={SQL Server};""SERVER=YourPC\\YourInstance;"  // 命名实例写法"DATABASE=TestDB;""UID=sa;""PWD=YourPassword;";db.setDatabaseName(connectionString);if (!db.open()) {qDebug() << "连接失败:" << db.lastError().text();return false;}qDebug() << "数据库连接成功!";return true;}static void disconnect() {QSqlDatabase::database().close();}
};

连接字符串示例

"DRIVER={SQL Server};SERVER=MyPC\\MyInstance,5000;DATABASE=MyDB;UID=sa;PWD=123456;"

2)主窗口类 MainWindow.cpp(含增删改查、事务处理)

#include "MainWindow.h"
#include "ui_MainWindow.h"MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);DatabaseManager::connect(); // 初始化连接loadDataToTable(); // 加载数据到表格
}MainWindow::~MainWindow() {DatabaseManager::disconnect();delete ui;
}// 加载数据到表格
void MainWindow::loadDataToTable() {QSqlQuery query;query.exec("SELECT * FROM Users");ui->tableWidget->setRowCount(0);while (query.next()) {int row = ui->tableWidget->rowCount();ui->tableWidget->insertRow(row);ui->tableWidget->setItem(row, 0, new QTableWidgetItem(query.value("ID").toString()));ui->tableWidget->setItem(row, 1, new QTableWidgetItem(query.value("Name").toString()));ui->tableWidget->setItem(row, 2, new QTableWidgetItem(query.value("Age").toString()));}
}// 添加用户
void MainWindow::on_btnAdd_clicked() {QSqlQuery query;query.prepare("INSERT INTO Users (Name, Age) VALUES (?, ?)");query.addBindValue(ui->txtName->text());query.addBindValue(ui->txtAge->text().toInt());if (!query.exec()) {qDebug() << "插入失败:" << query.lastError().text();} else {loadDataToTable(); // 刷新表格}
}// 删除用户
void MainWindow::on_btnDelete_clicked() {int selectedRow = ui->tableWidget->currentRow();if (selectedRow == -1) return;QString id = ui->tableWidget->item(selectedRow, 0)->text();QSqlQuery query;query.prepare("DELETE FROM Users WHERE ID = ?");query.addBindValue(id);if (!query.exec()) {qDebug() << "删除失败:" << query.lastError().text();} else {loadDataToTable(); // 刷新表格}
}// 执行事务处理示例
void MainWindow::on_btnTransaction_clicked() {QSqlDatabase::database().transaction(); // 开启事务QSqlQuery query;query.exec("UPDATE Users SET Age = Age + 1 WHERE Name = 'Alice'");query.exec("UPDATE Users SET Age = Age - 1 WHERE Name = 'Bob'");if (query.lastError().isValid()) {QSqlDatabase::database().rollback(); // 回滚qDebug() << "事务执行失败,已回滚";} else {QSqlDatabase::database().commit(); // 提交qDebug() << "事务执行成功";}
}

八、MY SQL

1)数据库连接类 DatabaseManager.h

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>class DatabaseManager {
public:static bool connect() {QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");db.setHostName("localhost");    // MySQL 服务器地址db.setPort(3306);               // MySQL 默认端口db.setDatabaseName("TestDB");   // 数据库名db.setUserName("qtuser");       // 用户名db.setPassword("123456");       // 密码if (!db.open()) {qDebug() << "连接失败:" << db.lastError().text();return false;}qDebug() << "数据库连接成功!";return true;}static void disconnect() {QSqlDatabase::database().close();}
};

2)主窗口类 MainWindow.cpp(含增删改查、事务处理)

#include "MainWindow.h"
#include "ui_MainWindow.h"MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);DatabaseManager::connect();loadDataToTable();  // 初始化加载数据
}MainWindow::~MainWindow() {DatabaseManager::disconnect();delete ui;
}// 加载数据到表格
void MainWindow::loadDataToTable() {QSqlQuery query("SELECT * FROM Users");ui->tableWidget->setRowCount(0);while (query.next()) {int row = ui->tableWidget->rowCount();ui->tableWidget->insertRow(row);ui->tableWidget->setItem(row, 0, new QTableWidgetItem(query.value("ID").toString()));ui->tableWidget->setItem(row, 1, new QTableWidgetItem(query.value("Name").toString()));ui->tableWidget->setItem(row, 2, new QTableWidgetItem(query.value("Age").toString()));}
}// 添加用户
void MainWindow::on_btnAdd_clicked() {QSqlQuery query;query.prepare("INSERT INTO Users (Name, Age) VALUES (?, ?)");query.addBindValue(ui->txtName->text());query.addBindValue(ui->txtAge->text().toInt());if (!query.exec()) {qDebug() << "插入失败:" << query.lastError().text();} else {loadDataToTable();  // 刷新表格}
}// 删除用户
void MainWindow::on_btnDelete_clicked() {int row = ui->tableWidget->currentRow();if (row == -1) return;QString id = ui->tableWidget->item(row, 0)->text();QSqlQuery query;query.prepare("DELETE FROM Users WHERE ID = ?");query.addBindValue(id);if (!query.exec()) {qDebug() << "删除失败:" << query.lastError().text();} else {loadDataToTable();  // 刷新表格}
}// 更新用户年龄
void MainWindow::on_btnUpdate_clicked() {int row = ui->tableWidget->currentRow();if (row == -1) return;QString id = ui->tableWidget->item(row, 0)->text();int newAge = ui->txtNewAge->text().toInt();QSqlQuery query;query.prepare("UPDATE Users SET Age = ? WHERE ID = ?");query.addBindValue(newAge);query.addBindValue(id);if (!query.exec()) {qDebug() << "更新失败:" << query.lastError().text();} else {loadDataToTable();  // 刷新表格}
}void MainWindow::on_btnTransaction_clicked() {QSqlDatabase::database().transaction();  // 开启事务QSqlQuery query;query.exec("UPDATE Users SET Age = Age + 1 WHERE Name = 'Alice'");query.exec("UPDATE Users SET Age = Age - 1 WHERE Name = 'Bob'");if (query.lastError().isValid()) {QSqlDatabase::database().rollback();qDebug() << "事务回滚!";} else {QSqlDatabase::database().commit();qDebug() << "事务提交!";}
}

九、SQLITE

1)数据库连接类 DatabaseManager.h

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>
#include <QStandardPaths>class DatabaseManager {
public:static bool connect() {// 数据库文件路径(自动创建)QString dbPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + "/mydatabase.db";QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName(dbPath);if (!db.open()) {qDebug() << "连接失败:" << db.lastError().text();return false;}qDebug() << "数据库连接成功!路径:" << dbPath;// 自动建表createTables();return true;}static void createTables() {QSqlQuery query;query.exec("CREATE TABLE IF NOT EXISTS Users (""ID INTEGER PRIMARY KEY AUTOINCREMENT,""Name TEXT NOT NULL,""Age INTEGER)");if (query.lastError().isValid()) {qDebug() << "建表失败:" << query.lastError().text();}}static void disconnect() {QSqlDatabase::database().close();}
};

2)主窗口类 MainWindow.cpp(含增删改查、事务处理)

#include "MainWindow.h"
#include "ui_MainWindow.h"MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);DatabaseManager::connect();loadDataToTable();  // 初始化加载数据
}MainWindow::~MainWindow() {DatabaseManager::disconnect();delete ui;
}// 加载数据到表格
void MainWindow::loadDataToTable() {QSqlQuery query("SELECT * FROM Users");ui->tableWidget->setRowCount(0);while (query.next()) {int row = ui->tableWidget->rowCount();ui->tableWidget->insertRow(row);ui->tableWidget->setItem(row, 0, new QTableWidgetItem(query.value("ID").toString()));ui->tableWidget->setItem(row, 1, new QTableWidgetItem(query.value("Name").toString()));ui->tableWidget->setItem(row, 2, new QTableWidgetItem(query.value("Age").toString()));}
}// 添加用户
void MainWindow::on_btnAdd_clicked() {QSqlQuery query;query.prepare("INSERT INTO Users (Name, Age) VALUES (:name, :age)");query.bindValue(":name", ui->txtName->text());query.bindValue(":age", ui->txtAge->text().toInt());if (!query.exec()) {qDebug() << "插入失败:" << query.lastError().text();} else {loadDataToTable();  // 刷新表格}
}// 删除用户
void MainWindow::on_btnDelete_clicked() {int row = ui->tableWidget->currentRow();if (row == -1) return;QString id = ui->tableWidget->item(row, 0)->text();QSqlQuery query;query.prepare("DELETE FROM Users WHERE ID = ?");query.addBindValue(id);if (!query.exec()) {qDebug() << "删除失败:" << query.lastError().text();} else {loadDataToTable();  // 刷新表格}
}// 更新用户年龄
void MainWindow::on_btnUpdate_clicked() {int row = ui->tableWidget->currentRow();if (row == -1) return;QString id = ui->tableWidget->item(row, 0)->text();int newAge = ui->txtNewAge->text().toInt();QSqlQuery query;query.prepare("UPDATE Users SET Age = ? WHERE ID = ?");query.addBindValue(newAge);query.addBindValue(id);if (!query.exec()) {qDebug() << "更新失败:" << query.lastError().text();} else {loadDataToTable();  // 刷新表格}
}// 批量插入数据(事务加速)
void MainWindow::on_btnBatchInsert_clicked() {QSqlDatabase::database().transaction();  // 开启事务QSqlQuery query;query.prepare("INSERT INTO Users (Name, Age) VALUES (?, ?)");for (int i = 0; i < 1000; ++i) {query.addBindValue("User_" + QString::number(i));query.addBindValue(20 + i % 10);query.exec();}if (query.lastError().isValid()) {QSqlDatabase::database().rollback();qDebug() << "批量插入失败,已回滚";} else {QSqlDatabase::database().commit();qDebug() << "批量插入成功,耗时优化 10x+";loadDataToTable();}
}

十、ORACLE

在使用Qt进行Oracle数据库操作时,通常有两种方法比较常见:使用Oracle的OCI(Oracle Call Interface)或者使用ODBC(Open Database Connectivity)。下面我将详细介绍如何使用这两种方法在Qt应用程序中操作Oracle数据库。

方法1:使用OCI

Oracle Call Interface (OCI) 是Oracle提供的一套C语言API,用于访问Oracle数据库。要在Qt中使用OCI,你需要先确保你的系统上安装了Oracle的客户端库和头文件,并且你的项目需要链接到这些库。
步骤:
1)Oracle 客户端安装
下载 Oracle Instant Client 的 ‌Basic‌ 和 ‌SDK‌ 包(需与 Qt 编译器位数一致)‌。解压到目录如 C:\oracle\instantclient_12_2,将 oci.dll 所在路径加入系统环境变量 PATH

2)Qt OCI 驱动编译

cd Qt/6.5.0/Src/qtbase/src/plugins/sqldrivers/oci
qmake "INCLUDEPATH+=C:/oracle/instantclient_12_2/sdk/include" "LIBS+=-LC:/oracle/instantclient_12_2 -loci"
nmake  # 或make

编译生成的 qsqloci.dll 需复制到 Qt/6.5.0/mingw_64/plugins/sqldrivers
3)在Qt项目中包含头文件和链接库:

#include <oci.h>

4) 在.pro文件中添加链接器选项:

QT += core gui sql
CONFIG += c++17# 配置 Oracle 库路径
win32 {LIBS += -LC:/oracle/instantclient_12_2 -lociINCLUDEPATH += C:/oracle/instantclient_12_2/sdk/include
}

‌完整实例代码:

1)数据库连接类 OracleManager.h

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>class OracleManager {
public:static bool connect(const QString &serviceName) {QSqlDatabase db = QSqlDatabase::addDatabase("QOCI");db.setHostName("192.168.1.100");        // Oracle 服务器 IPdb.setPort(1521);                       // 默认端口db.setDatabaseName(serviceName);        // 服务名(非 SID)db.setUserName("scott");                // 用户名db.setPassword("tiger");                // 密码if (!db.open()) {qDebug() << "[ERROR] 连接失败:" << db.lastError().text() << "‌:ml-citation{ref="1,6" data="citationList"}";return false;}qDebug() << "数据库连接成功!";return true;}static void disconnect() {QSqlDatabase::database().close();}
};

2)主窗口类 MainWindow.cpp(含增删改查、事务处理)

// 创建表
void MainWindow::createTable() {QSqlQuery query;query.exec("CREATE TABLE Employees (""EmpID NUMBER PRIMARY KEY,""Name NVARCHAR2(50),""Salary NUMBER(10,2))");if(query.lastError().isValid()) qDebug() << "建表错误:" << query.lastError().text() << "‌:ml-citation{ref="8" data="citationList"}";
}// 插入数据(绑定参数)
void MainWindow::onInsertClicked() {QSqlQuery query;query.prepare("INSERT INTO Employees (EmpID, Name, Salary) VALUES (:id, :name, :sal)");query.bindValue(":id", 1001);query.bindValue(":name", "张三");query.bindValue(":sal", 8500.50);if (!query.exec()) qDebug() << "插入失败:" << query.lastError().text() << "‌:ml-citation{ref="3,6" data="citationList"}";
}// 查询数据(事务处理)
void MainWindow::onQueryClicked() {QSqlDatabase::database().transaction();QSqlQuery query("SELECT * FROM Employees");while (query.next()) {int id = query.value("EmpID").toInt();QString name = query.value("Name").toString();double salary = query.value("Salary").toDouble();// 显示到 UI...}if (query.lastError().isValid()) {QSqlDatabase::database().rollback();qDebug() << "事务回滚!" << "‌:ml-citation{ref="8" data="citationList"}";} else {QSqlDatabase::database().commit();}
}
    方法2:使用ODBC

    ODBC提供了一个数据库无关的应用程序编程接口(API),允许应用程序通过ODBC驱动程序与数据库进行通信。Qt提供了对ODBC的支持,可以通过QSqlDatabaseQSqlQuery类来操作。

    QSqlDatabase db = QSqlDatabase::addDatabase("QODBC");
    db.setHostName("hostname"); // 通常是localhost或服务器地址
    db.setDatabaseName("DSN_NAME"); // 数据源名称,在ODBC中配置的DSN名称
    db.setUserName("username");
    db.setPassword("password");if (db.open()) {QSqlQuery query(db);query.exec("SELECT * FROM your_table");while (query.next()) {// 处理查询结果...}db.close();
    } else {qDebug() << "Database connection failed";
    }

    相关文章:

    QT编程之数据库开发

    一、架构层次 ‌用户接口层‌ ‌QSqlQueryModel‌&#xff1a;管理SQL查询结果&#xff0c;提供表格数据模型用于展示‌‌QSqlTableModel‌&#xff1a;支持直接操作数据库表&#xff08;增删改查&#xff09;‌‌QSqlRelationalTableModel‌&#xff1a;支持带外键关联的复杂表…...

    【10】高效存储MongoDB的用法

    目录 一、什么是MongoDB 二、准备工作 &#xff08;1&#xff09;安装MongoDB ​&#xff08;2&#xff09;安装pymongo库 三、连接MongoDB 四、指定数据库 五、指定集合 六、插入数据 &#xff08;1&#xff09; insert 方法 &#xff08;2&#xff09;insert_one(…...

    使用Qdrant等其他向量数据库时需要将将numpy 数组转换为列表 确保数据能被正确处理和序列化,避免类型不兼容的问题。

    在使用Qdrant等其他向量数据库时需要 转换 numpy 数组为列表主要是为了确保数据能被正确处理和序列化&#xff0c;避免类型不兼容的问题。具体原因如下&#xff1a; 序列化兼容性&#xff1a; 很多数据库接口、API 或者 JSON 序列化工具只能处理 Python 的内置类型&#xff08;…...

    mayfly-go开源的一站式 Web 管理平台

    mayfly-go 是一款开源的一站式 Web 管理平台&#xff0c;旨在通过统一的界面简化 Linux 服务器、数据库&#xff08;如 MySQL、PostgreSQL、Redis、MongoDB 等&#xff09;的运维管理。以下从多个维度对其核心特性、技术架构、应用场景及生态进行详细解析&#xff1a; 一、核心…...

    Linux中的yum和vim工具使用总结

    在Linux系统管理和文本编辑中&#xff0c;yum和vim是两个非常重要的工具。yum作为包管理器帮助我们轻松安装和管理软件&#xff0c;而vim则是一个功能强大的文本编辑器。下面我将对这两个工具进行详细介绍。 一、YUM包管理器 1. YUM简介 YUM (Yellowdog Updater Modified) 是…...

    笔记:代码随想录算法训练营day58:101.孤岛的总面积、102.沉没孤岛、103.水流问题、104.建造最大岛屿

    学习资料&#xff1a;代码随想录 文中含大模型生成内容 101. 孤岛的总面积 卡码网&#xff1a;101. 孤岛的总面积 所以找周边都是水的陆地的方法就是找边缘的陆地然后删除它连同它的连通的陆地 深搜 #include <iostream> #include <vector> using namespac…...

    Rust语言介绍和猜数字游戏的实现

    文章目录 Rust语言介绍和猜数字游戏的实现cargo是什么使用Rust编写猜数字 Rust语言介绍和猜数字游戏的实现 Rust语言是一种系统编程语言&#xff0c;核心强调安全性、并发性以及高性能&#xff0c;由类似于C/C的底层控制能力&#xff0c;性能也非常接近&#xff0c;Rust有一些…...

    高并发库存系统是否适合使用 ORM(Hibernate / MyBatis)

    在设计高并发的库存管理系统时&#xff0c;数据层的选择至关重要。许多企业开发中习惯使用 ORM&#xff08;如 Hibernate、MyBatis&#xff09;来简化数据库访问&#xff0c;但在高并发、高吞吐的场景下&#xff0c;ORM 的适用性往往成为争议焦点。本文将探讨高并发库存系统是否…...

    Spring Boot中接口数据字段为 Long 类型时,前端number精度丢失问题解决方案

    Spring Boot中接口数据字段为 Long 类型时&#xff0c;前端number精度丢失问题解决方案 在Spring Boot中&#xff0c;当接口数据字段为 Long 类型时&#xff0c;返回页面的JSON中该字段通常会被序列化为数字类型。 例如&#xff0c;一个Java对象中有一个 Long 类型的属性 id …...

    Java-servlet(七)详细讲解Servlet注解

    Java-servlet&#xff08;七&#xff09;详细讲解Servlet注解 前言一、注解的基本概念二、Override 注解2.1 作用与优势2.2 示例代码 三、Target 注解3.1 定义与用途3.2 示例代码 四、WebServlet 注解4.1 作用4.2 示例代码 五、反射与注解5.1 反射的概念5.2 注解与反射的结合使…...

    OpenCV Imgproc 模块使用指南(Python 版)

    一、模块概述 imgproc 模块是 OpenCV 的图像处理核心&#xff0c;提供从基础滤波到高级特征提取的全流程功能。核心功能包括&#xff1a; 图像滤波&#xff1a;降噪、平滑、锐化几何变换&#xff1a;缩放、旋转、透视校正颜色空间转换&#xff1a;BGR↔灰度 / HSV/Lab 等阈值…...

    PostgreSQL:简介与安装部署

    &#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…...

    流畅如丝:利用requestAnimationFrame优化你的Web动画体验

    requestAnimationFrame 是前端开发中用于优化动画性能的 API。它允许浏览器在下一次重绘之前执行指定的回调函数&#xff0c;通常用于实现平滑的动画效果。 1.作用 优化性能&#xff1a;requestAnimationFrame 会根据浏览器的刷新率&#xff08;通常是 60Hz&#xff0c;即每秒…...

    OpenCV 基础模块 Python 版

    OpenCV 基础模块权威指南&#xff08;Python 版&#xff09; 一、模块全景图 plaintext OpenCV 架构 (v4.x) ├─ 核心层 │ ├─ core&#xff1a;基础数据结构与操作&#xff08;Mat/Scalar/Point&#xff09; │ └─ imgproc&#xff1a;图像处理流水线&#xff08;滤…...

    代码随想录算法训练营第十五天 | 数组 |长度最小的子数组和螺旋矩阵II

    长度最小的子数组 【题目简介】 【自写数组解法】 class Solution:def minSubArrayLen(self, target: int, nums: List[int]) -> int:minLength float(inf)slow 0fast 0cur_sum nums[slow]# 终止条件&#xff1a;fast不能超过最大索引值while slow < fast and fas…...

    C++ 入门第27天:异常处理详细讲解

    往期回顾&#xff1a; C 入门第24天&#xff1a;C11 多线程基础-CSDN博客 C 入门第25天&#xff1a;线程池&#xff08;Thread Pool&#xff09;基础-CSDN博客 C 入门第26天&#xff1a;文件与流操作基础-CSDN博客 C 入门第27天&#xff1a;异常处理详细讲解 前言 在 C 开发中…...

    Powershell WSL导出导入ubuntu22.04.5子系统

    导出Linux子系统 导出位置在C盘下,根据自己的实际情况更改即可Write-Host "export ubuntu22.04.5" -ForegroundColor Green wsl --export Ubuntu-22.04 c:\Ubuntu-22.04.tar 导入Linux子系统 好处是目录可用在任意磁盘路径,便于迁移不同的设备之间Write-Host &quo…...

    中文文献去哪里查找,个人下载知网、万方、维普文献途径

    国内三大知识库知网、万方、维普是查找中文文献常用数据库&#xff0c;本文将以实例演示个人下载这三个数据库文献的途径及过程。 先说下途径&#xff1a; 获取知网、万方、维普数据库资源可去文献党下载器网站&#xff1a; 使用方法&#xff1a; 在文献党下载器官网下载安装…...

    玩转C#函数:参数、返回值与游戏中的攻击逻辑封装

    Langchain系列文章目录 01-玩转LangChain&#xff1a;从模型调用到Prompt模板与输出解析的完整指南 02-玩转 LangChain Memory 模块&#xff1a;四种记忆类型详解及应用场景全覆盖 03-全面掌握 LangChain&#xff1a;从核心链条构建到动态任务分配的实战指南 04-玩转 LangChai…...

    简易shell

    自主实现shell done&#xff0c;故意写成&#xff0c;表示先赋值&#xff0c;再判断&#xff0c;分割之后&#xff0c;strtok会返回NULL&#xff0c;刚好让gArgv最后一个元素是NULL&#xff0c;并且while判断结束 Makefile 1 myshell:myshell.c …...

    注意力机制,本质上是在做什么?

    本文以自注意机制为例&#xff0c;输入一个4*4的矩阵 如下&#xff1a; input_datatorch.tensor([[1,2,3,4], [5,6,7,8], [9,10,11,12], [13,14,15,16] ],dtypetorch.float) 得到Q和K的转置如下。 此时&#xff0c;计算QK^T ,得到如下结果 第一行第一个位置就是第一条样本和第…...

    【机器学习-模型评估】

    “评估”已建立的模型 在进行回归和分类时&#xff0c;为了进行预测&#xff0c;定义了预测函数fθ(x) 然后根据训练数据求出了预测函数的参数θ(即对目标函数进行微分&#xff0c;然后求出参数更新表达式的操作) 之前求出参数更新表达式之后就结束了。但是&#xff0c;其实我…...

    19681 01背包

    19681 01背包 ⭐️难度&#xff1a;中等 &#x1f31f;考点&#xff1a;动态规划、01背包 &#x1f4d6; &#x1f4da; import java.util.Arrays; import java.util.LinkedList; import java.util.Queue; import java.util.Scanner;public class Main {static int N 10001…...

    Transformer-GRU、Transformer、CNN-GRU、GRU、CNN五模型多变量回归预测

    Transformer-GRU、Transformer、CNN-GRU、GRU、CNN五模型多变量回归预测 目录 Transformer-GRU、Transformer、CNN-GRU、GRU、CNN五模型多变量回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Transformer-GRU、Transformer、CNN-GRU、GRU、CNN五模型多变量回归预…...

    基于CAMEL 的Workforce 实现多智能体协同工作系统

    文章目录 一、workforce 简介1.架构设计2.通信机制 二、workforce 工作流程图示例1.用户角色2.工作流程 三、workforce 中重要函数说明1.__init__函数2.add_single_agent_worker 函数3.add_role_playing_worker 函数4.add_workforce 函数 四、基于workforce实现多智能体协调&am…...

    炫酷的3D按钮效果实现 - CSS3高级特性应用

    炫酷的3D按钮效果实现 - CSS3高级特性应用 这里写目录标题 炫酷的3D按钮效果实现 - CSS3高级特性应用项目介绍核心技术实现1. 基础结构设计2. 视觉效果实现2.1 背景渐变2.2 立体感营造 3. 交互动效设计3.1 悬停效果3.2 按压效果 技术要点分析1. 深度层次感2. 动画过渡3. 性能优…...

    AI视频是否会影响原创价值

    AI视频是否会影响原创价值 AI视频带来全民创意对原创内容的影响 随着AI技术的发展&#xff0c;AI视频技术在视频领域的影响也逐渐凸显&#xff0c;从自动剪辑、特效生成到基于文本或语音自动生成视频内容&#xff0c;这一系列的进步极大地降低了视频制作的技术门槛与成本。这种…...

    代码随想录刷题day50|(回溯算法篇)131.分割回文串▲

    目录 一、回溯算法基础知识 二、分割回文串思路 2.1 如何切割 2.2 判断回文 2.3 回溯三部曲 2.4 其他问题 三、相关算法题目 四、总结 一、回溯算法基础知识 详见&#xff1a;代码随想录刷题day46|&#xff08;回溯算法篇&#xff09;77.组合-CSDN博客 二、分割回文…...

    SpringCloud 学习笔记3(OpenFeign)

    OpenFeign 微服务之间的通信方式&#xff0c;通常有两种&#xff1a;RPC 和 HTTP。 简言之&#xff0c;RPC 就是像调用本地方法一样调用远程方法。 在 SpringCloud 中&#xff0c;默认是使用 HTTP 来进行微服务的通信&#xff0c;最常用的实现形式有两种&#xff1a; RestTem…...

    Python与区块链隐私保护技术:如何在去中心化世界中保障数据安全

    Python与区块链隐私保护技术:如何在去中心化世界中保障数据安全 在区块链世界里,透明性和不可篡改性是两大核心优势,但这也带来了一个悖论——如何在公开账本的同时保障用户隐私?如果你的交易记录对所有人可见,如何防止敏感信息泄露? Python 作为区块链开发中最受欢迎的…...

    基于32单片机的无人机直流电机闭环调速系统设计

    标题:基于32单片机的无人机直流电机闭环调速系统设计 内容:1.摘要 本文针对无人机直流电机调速需求&#xff0c;设计了基于32单片机的无人机直流电机闭环调速系统。背景在于无人机应用场景不断拓展&#xff0c;对电机调速精度和稳定性要求日益提高。目的是开发一套高精度、响应…...

    QT 图表(拆线图,栏状图,饼状图 ,动态图表)

    效果 折线图 // 创建折线数据系列// 创建折线系列QLineSeries *series new QLineSeries;// series->append(0, 6);// series->append(2, 4);// series->append(3, 8);// 创建图表并添加系列QChart *chart new QChart;chart->addSeries(series);chart->setTit…...

    预测性维护:Ubuntu边缘计算机如何降低电梯故障率

    在现代城市中&#xff0c;电梯作为垂直交通的重要工具&#xff0c;其运行状态直接关系到人们的出行安全和效率。传统的电梯监控系统往往依赖于中心化的数据处理&#xff0c;存在响应慢、数据量大、实时性差等问题。而边缘协议网关&#xff08;Edge Protocol Gateway&#xff09…...

    MyBatis plus详解

    核心功能 代码生成器 它能够依据数据库表结构&#xff0c;自动生成涵盖实体类、Mapper 接口、Mapper XML 文件、Service 接口与实现类等在内的基础代码。开发人员只需简单配置数据库连接信息、表名以及生成代码的相关参数&#xff0c;即可快速生成符合项目规范的基础代码&…...

    【数据挖掘】数据预处理——以鸢尾花数据集为例

    数据预处理——以鸢尾花数据集为例 一、实验手册&#xff08;一&#xff09;实验目的&#xff08;二&#xff09;实验原理&#xff08;三&#xff09;实验环境&#xff08;四&#xff09;实验步骤&#xff08;五&#xff09;实验报告要求 二、案例代码&#xff08;以鸢尾花数据…...

    根据文件名称查询文件所在位置

    在 Linux 中&#xff0c;根据文件名称查询文件所在位置主要通过命令行工具实现&#xff0c;以下是几种常用方法&#xff1a; --- ### **1. 使用 find 命令&#xff08;最灵活&#xff09;** find 命令可以递归搜索指定目录下的文件&#xff0c;支持按名称、类型、时间等条件过…...

    记一次wsl2+docker无法运行的经历

    前情提要 由于某个大创项目的需要和对猫娘机器人的迫切渴求&#xff08;bushi 需要在电脑里面安装docker desktop。由于电脑里面安装了wsl2环境 因此决定使用wsl2dockerdesktop的方式配置docker 遇到的问题 在像往常一样安装docker desktop并且启动时 提示错误&#xff1a; …...

    XSS介绍通关XSS-Labs靶场

    目录 XSS XSS的类型 1.存储型XSS&#xff08;PXSS&#xff09;&#xff1a; 2. 反射型XSS&#xff08;N-PXSS&#xff09;&#xff1a; 3. DOM型XSS&#xff1a; 4. 突变型XSS&#xff08;mXSS&#xff09;&#xff1a; 5. 通用型XSS&#xff08;UXSS&#xff09;&#x…...

    枚举的定义及其使用

    在Java中&#xff0c;enum&#xff08;枚举&#xff09;是一个特殊的类&#xff0c;用于表示一组常量。enum类型在Java中提供了一种类型安全的方式来定义常量&#xff0c;相比传统的常量&#xff08;如public static final变量&#xff09;&#xff0c;它更加简洁、类型安全&am…...

    [特殊字符][特殊字符][特殊字符][特殊字符][特殊字符][特殊字符]壁紙 流光染墨,碎影入梦

    #Cosplay #&#x1f9da;‍♀️Bangni邦尼&#x1f430;. #&#x1f4f7; 穹妹 Set.01 #后期圈小程序 琼枝低垂&#xff0c;霜花浸透夜色&#xff0c;风起时&#xff0c;微光轻拂檐角&#xff0c;洒落一地星辉。远山隐于烟岚&#xff0c;唯余一抹青黛&#xff0c;勾勒出天光水…...

    996引擎-接口测试:消息Tips

    996引擎-接口测试:消息Tips 发送视野内广播消息 sendrefluamsg发送聊天框消息 sendmsg发送地图消息 sendmapmsg打印消息到控制台 release_print发送自定义颜色的文字信息 guildnoticemsg测试NPC参考资料发送视野内广播消息 sendrefluamsg function npc_test_onclick1(player)-…...

    Redis设计与实现-底层实现

    Redis底层实现 1、事件1.1 文件事件1.2 时间事件1.3 事件调度 2、Redis客户端2.1 客户端的相关属性2.2 客户端的创建与关闭2.2.1 普通客户端的创建2.2.2 普通客户端的关闭2.2.3 AOF的伪客户端2.2.4 Lua脚本的伪客户端 3、Redis服务端3.1 命令请求的执行过程3.1.1 客户端发送命令…...

    acwing1295. X的因子链

    题目链接&#xff1a;1295. X的因子链 - AcWing题库 算法&#xff1a;数论线性筛法求素数 x如果想要尽可能多的分为几个因子&#xff0c;那么就应该分成素数&#xff0c;因为如果是合数说明还能分。 题目要求求出①这段序列的最大长度和②最大长度序列的个数 最大长度&#x…...

    练习-班级活动(map存储键值对)

    问题描述 小明的老师准备组织一次班级活动。班上一共有 n 名 (n 为偶数) 同学&#xff0c;老师想把所有的同学进行分组&#xff0c;每两名同学一组。为了公平&#xff0c;老师给每名同学随机分配了一个 n 以内的正整数作为 id&#xff0c;第 i 名同学的 id 为 ai​。 老师希望…...

    34-三数之和

    给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足 nums[i] nums[j] nums[k] 0 。请你返回所有和为 0 且不重复的三元组。 注意&#xff1a;答案中不可以包含重复的三元组。 方法一&…...

    Excel online开始支持Copilot高级数据分析:Python提供强大的数据见解

    前文讲过Excel中的copilot可以直接调用Python进行高级数据分析&#xff1a; Copilot&#xff1a;Excel中的Python高级分析来了 Python in Excel高级分析&#xff1a;一键RFM分析 超越DeepSeek&#xff1a;Copilot in Excel高级数据分析原生支持Python无需安装软件 零代码、…...

    【数据结构】kmp算法介绍+模板代码

    目录 1.kmp算法介绍 2.应用场景 3.KMP与暴力算法比较 4.模板代码 KMP算法是一种高效的字符串匹配算法&#xff0c;用于在文本串中快速查找模式串的所有出现位置。其核心思想是通过预处理模式串&#xff0c;避免在匹配失败时进行不必要的回溯&#xff0c;从而将时间复杂度优…...

    python关键字汇总

    文章目录 1. 变量与类型相关2. 控制流相关3. 函数与类相关4. 异常处理相关5. 模块相关6. 其他 在 Python 3 里有 35 个关键字&#xff0c;它们各自具备特定的用途与意义 1. 变量与类型相关 True、False 意义&#xff1a;布尔类型的常量&#xff0c;分别代表逻辑真与逻辑假。示…...

    六十天前端强化训练之第二十五天之组件生命周期大师级详解(Vue3 Composition API 版)

    欢迎来到编程星辰海的博客讲解 看完可以给一个免费的三连吗&#xff0c;谢谢大佬&#xff01; 目录 一、生命周期核心知识 1.1 生命周期全景图 1.2 生命周期钩子详解 1.2.1 初始化阶段 1.2.2 挂载阶段 1.2.3 更新阶段 1.2.4 卸载阶段 1.3 生命周期执行顺序 1.4 父子组…...

    油候插件、idea、VsCode插件推荐(自用)

    开发软件&#xff1a; 之前的文章&#xff1a; 开发必装最实用工具软件与网站 推荐一下我使用的开发工具 目前在用的 油候插件 AC-baidu-重定向优化百度搜狗谷歌必应搜索_favicon_双列 让查询变成多列&#xff0c;而且可以流式翻页 Github 增强 - 高速下载 github下载 TimerHo…...