qt 操作多个sqlite文件
qt 操作多个sqlite文件
- Chapter1 qt 操作多个sqlite文件
- 1. 引入必要的头文件
- 2. 创建并连接多个SQLite数据库
- 3. 代码说明
- 4. 注意事项
- Chapter2 qt 多线程操作sqlite多文件
- 1. 引入必要的头文件
- 2. 创建数据库操作的工作线程类
- 3. 在主线程中创建并启动多个工作线程
- 4. 代码说明
- 5. 运行结果
- 6. 注意事项
- Chapter3 QSqlQuery增删改查操作
- 1.插入一条记录(增)
- 2.查询字段(查)
- 3.删除字段(删)
- 4.更新字段(改)
- Chapter4 深入解析 Qt 中的 bindValue 方法
- 引言
- 1. bindValue 方法简介
- 2. 基本语法
- 3. 参数化查询的优势
- 4. 使用 bindValue 方法
- 5. 示例代码
- 6. 处理查询结果
- 7. 示例代码
- 8. 错误处理
- 9. 事务处理
Chapter1 qt 操作多个sqlite文件
在Qt中操作多个SQLite数据库文件可以通过创建多个QSqlDatabase对象来实现。每个QSqlDatabase对象代表一个独立的数据库连接。以下是一个简单的示例,展示如何在Qt中操作多个SQLite数据库文件。
1. 引入必要的头文件
#include <QCoreApplication>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>
2. 创建并连接多个SQLite数据库
int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 创建并连接第一个SQLite数据库QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE", "connection1");db1.setDatabaseName("database1.db");if (!db1.open()) {qDebug() << "Error: Could not open database1.db";return -1;}// 创建并连接第二个SQLite数据库QSqlDatabase db2 = QSqlDatabase::addDatabase("QSQLITE", "connection2");db2.setDatabaseName("database2.db");if (!db2.open()) {qDebug() << "Error: Could not open database2.db";return -1;}// 在第一个数据库中执行查询QSqlQuery query1(db1);if (!query1.exec("CREATE TABLE IF NOT EXISTS table1 (id INTEGER PRIMARY KEY, name TEXT)")) {qDebug() << "Error: Could not create table in database1.db" << query1.lastError();}// 在第二个数据库中执行查询QSqlQuery query2(db2);if (!query2.exec("CREATE TABLE IF NOT EXISTS table2 (id INTEGER PRIMARY KEY, value INTEGER)")) {qDebug() << "Error: Could not create table in database2.db" << query2.lastError();}// 插入数据到第一个数据库if (!query1.exec("INSERT INTO table1 (name) VALUES ('Alice')")) {qDebug() << "Error: Could not insert data into database1.db" << query1.lastError();}// 插入数据到第二个数据库if (!query2.exec("INSERT INTO table2 (value) VALUES (100)")) {qDebug() << "Error: Could not insert data into database2.db" << query2.lastError();}// 关闭数据库连接db1.close();db2.close();return a.exec();
}
3. 代码说明
QSqlDatabase::addDatabase(“QSQLITE”, “connection1”): 创建一个名为connection1的数据库连接。"QSQLITE"表示使用SQLite数据库驱动。
db1.setDatabaseName(“database1.db”): 设置数据库文件的名称。如果文件不存在,SQLite会自动创建它。
db1.open(): 打开数据库连接。如果打开失败,返回false。
QSqlQuery query1(db1): 创建一个与db1关联的查询对象。所有通过query1执行的SQL语句都会在db1中执行。
query1.exec(“CREATE TABLE …”): 执行SQL语句。如果执行失败,可以通过query1.lastError()获取错误信息。
db1.close(): 关闭数据库连接。
4. 注意事项
连接名称: 每个数据库连接必须有一个唯一的名称(如"connection1"和"connection2")。如果不指定名称,Qt会使用默认连接。
资源管理: 确保在使用完数据库后关闭连接,以释放资源。
错误处理: 在实际应用中,应该对每个数据库操作进行错误处理,以确保程序的健壮性。
通过这种方式,你可以在Qt中同时操作多个SQLite数据库文件。
Chapter2 qt 多线程操作sqlite多文件
在Qt中使用多线程操作多个SQLite数据库文件时,需要注意SQLite的线程安全性以及Qt的多线程机制。SQLite默认支持多线程操作,但需要确保每个线程使用独立的数据库连接,以避免竞争条件。
以下是一个示例,展示如何在Qt中使用多线程操作多个SQLite数据库文件。
1. 引入必要的头文件
#include <QCoreApplication>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QThread>
#include <QDebug>
#include <QList>
#include <QMutex>
2. 创建数据库操作的工作线程类
每个线程负责操作一个独立的SQLite数据库文件。
class DatabaseWorker : public QObject
{Q_OBJECTpublic:DatabaseWorker(const QString &connectionName, const QString &databaseName, QObject *parent = nullptr): QObject(parent), m_connectionName(connectionName), m_databaseName(databaseName) {}public slots:void process(){// 创建数据库连接QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE", m_connectionName);db.setDatabaseName(m_databaseName);if (!db.open()) {qDebug() << "Error: Could not open database" << m_databaseName << "in thread" << QThread::currentThread();emit finished();return;}// 执行数据库操作QSqlQuery query(db);if (!query.exec("CREATE TABLE IF NOT EXISTS test (id INTEGER PRIMARY KEY, value TEXT)")) {qDebug() << "Error: Could not create table in" << m_databaseName << query.lastError();}for (int i = 0; i < 10; ++i) {if (!query.exec(QString("INSERT INTO test (value) VALUES ('%1')").arg(QString::number(i)))) {qDebug() << "Error: Could not insert data into" << m_databaseName << query.lastError();}}qDebug() << "Database" << m_databaseName << "processed in thread" << QThread::currentThread();// 关闭数据库连接db.close();emit finished();}signals:void finished();private:QString m_connectionName;QString m_databaseName;
};
3. 在主线程中创建并启动多个工作线程
int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 定义数据库文件列表QList<QString> databaseFiles = {"database1.db", "database2.db", "database3.db"};// 创建线程和工作者对象QList<QThread*> threads;QList<DatabaseWorker*> workers;for (int i = 0; i < databaseFiles.size(); ++i) {QString connectionName = QString("connection%1").arg(i);QString databaseName = databaseFiles.at(i);// 创建工作线程QThread *thread = new QThread();DatabaseWorker *worker = new DatabaseWorker(connectionName, databaseName);// 将工作者移动到线程中worker->moveToThread(thread);// 连接信号和槽QObject::connect(thread, &QThread::started, worker, &DatabaseWorker::process);QObject::connect(worker, &DatabaseWorker::finished, thread, &QThread::quit);QObject::connect(worker, &DatabaseWorker::finished, worker, &DatabaseWorker::deleteLater);QObject::connect(thread, &QThread::finished, thread, &QThread::deleteLater);// 启动线程thread->start();// 保存线程和工作者对象threads.append(thread);workers.append(worker);}// 等待所有线程完成for (QThread *thread : threads) {thread->wait();}qDebug() << "All databases processed.";return a.exec();
}
4. 代码说明
DatabaseWorker类:
每个DatabaseWorker对象负责操作一个SQLite数据库文件。
使用QSqlDatabase::addDatabase创建独立的数据库连接,并通过moveToThread将工作者对象移动到独立的线程中。
多线程机制:
每个数据库操作在一个独立的线程中执行,避免阻塞主线程。
使用QThread管理线程的生命周期,并通过信号槽机制实现线程间通信。
线程安全性:
SQLite支持多线程操作,但每个线程必须使用独立的数据库连接。
如果多个线程需要访问同一个数据库文件,可以使用QMutex或SQLite的写锁机制来避免竞争条件。
资源管理:
在线程完成任务后,调用quit()和deleteLater()释放线程和工作者对象。
5. 运行结果
程序会创建多个线程,每个线程操作一个独立的SQLite数据库文件。输出示例如下:
复制
Database “database1.db” processed in thread QThread(0x12345678)
Database “database2.db” processed in thread QThread(0x23456789)
Database “database3.db” processed in thread QThread(0x34567890)
All databases processed.
6. 注意事项
SQLite的线程模式:
SQLite默认支持多线程操作,但需要确保每个线程使用独立的连接。
如果需要更高的并发性,可以启用SQLite的WAL模式(Write-Ahead Logging)。
线程数量:
不要创建过多的线程,否则可能会导致性能下降。可以根据实际需求调整线程数量。
错误处理:
在实际应用中,应该对每个数据库操作进行错误处理,以确保程序的健壮性。
通过这种方式,你可以在Qt中高效地使用多线程操作多个SQLite数据库文件。
Chapter3 QSqlQuery增删改查操作
我们需要插入多条数据,此时可以使用 QSqlQuery::exec() 函数一条一条插入数据,但是这里我们选择了另外一种方法:批量执行。首先,我们使用 QSqlQuery::prepare() 函数对这条 SQL 语句进行预处理,问号?相当于占位符,预示着以后我们可以使用实际数据替换这些位置。简单说明一下,预处理是数据库提供的一种特性,它会将 SQL 语句进行编译,性能和安全性都要优于普通的 SQL 处理。在上面的代码中,我们使用一个字符串列表 names 替换掉第一个问号的位置,一个整型列表 ages 替换掉第二个问号的位置,利用 QSqlQuery::addBindValue() 我们将实际数据绑定到这个预处理的 SQL 语句上。需要注意的是,names 和 ages 这两个列表里面的数据需要一一对应。然后我们调用 QSqlQuery::execBatch() 批量执行 SQL,之后结束该对象。这样,插入操作便完成了。
另外说明一点,我们这里使用了 ODBC 风格的?占位符,同样,我们也可以使用 Oracle 风格的占位符:
query.prepare("INSERT INTO student (name, age) VALUES (:name, :age)");
此时,我们就需要使用
query.bindValue(":name", names);
query.bindValue(":age", ages);
进行绑定。Oracle 风格的绑定最大的好处是,绑定的名字和值很清晰,与顺序无关。但是这里需要注意,bindValue() 函数只能绑定一个位置。比如
query.prepare("INSERT INTO test (name1, name2) VALUES (:name, :name)");
// ...
query.bindValue(":name", name);
只能绑定第一个 :name 占位符,不能绑定到第二个。
接下来我们依旧使用同一个查询对象执行一个 SELECT 语句。如果存在查询结果,QSqlQuery::next() 会返回 true,直到到达结果最末,返回 false,说明遍历结束。我们利用这一点,使用 while 循环即可遍历查询结果。使用 QSqlQuery::value() 函数即可按照 SELECT 语句的字段顺序获取到对应的数据库存储的数据。
对于数据库事务的操作,我们可以使用 QSqlDatabase::transaction() 开启事务,QSqlDatabase::commit() 或者 QSqlDatabase::rollback() 结束事务。使用 QSqlDatabase::database() 函数则可以根据名字获取所需要的数据库连接。
bool Widget::saveToDb(double value1, double value2, double value3, double value4)
{// 插入数据到第二个数据库QSqlQuery query2(db2);query2.prepare("INSERT INTO table2 (value1, value2, value3, value4) VALUES (:value1, :value2, :value3, :value4)");query2.bindValue(":value1", value1);query2.bindValue(":value2", value2);query2.bindValue(":value3", value3);query2.bindValue(":value4", value4);if (!query2.exec()) {qDebug() << "Error: Could not insert data into database2.db" << query2.lastError();QMessageBox::information(this, "错误", "插入记录失败: \n" + query2.lastError().text());}QMessageBox::information(this, "提示", "插入完成!");return true;
}void Widget::on_pBtn_insert_clicked()
{double v1 = ui->lineEdit1->text().toDouble();double v2 = ui->lineEdit2->text().toDouble();double v3 = ui->lineEdit3->text().toDouble();double v4 = ui->lineEdit4->text().toDouble();this->saveToDb(v1, v2, v3, v4);
}
1.插入一条记录(增)
QSqlQuery query;
query.prepare("INSERT INTO table_name (column1, column2, column3) VALUES (:value1, :value2, :value3)");
query.bindValue(":value1", value1);
query.bindValue(":value2", value2);
query.bindValue(":value3", value3);
query.exec();
2.查询字段(查)
QSqlQuery query;
query.prepare("SELECT * FROM table_name WHERE column1 = :value1 AND column2 = :value2 AND column3 = :value3");
query.bindValue(":value1", value1);
query.bindValue(":value2", value2);
query.bindValue(":value3", value3);
query.exec();// 处理查询结果
while (query.next()) {// 在这里处理每一行的数据
}
3.删除字段(删)
QSqlQuery query;
query.prepare("DELETE FROM table_name WHERE column1 = :value1 AND column2 = :value2 AND column3 = :value3");
query.bindValue(":value1", value1);
query.bindValue(":value2", value2);
query.bindValue(":value3", value3);
query.exec();
4.更新字段(改)
QSqlQuery query;
query.prepare("UPDATE table_name SET column2 = :value2, column3 = :value3 WHERE column1 = :value1");
query.bindValue(":value1", value1);
query.bindValue(":value2", value2);
query.bindValue(":value3", value3);
query.exec();
Chapter4 深入解析 Qt 中的 bindValue 方法
原文链接:https://blog.csdn.net/festaw/article/details/140503911
引言
在应用程序开发中,数据库交互是常见的需求之一。为了确保应用程序的安全性和数据的准确性,Qt 提供了多种工具和方法来帮助开发者实现这一目标。其中,bindValue 方法是 QSqlQuery 类中一个非常关键的成员函数,用于实现参数化查询。本文将详细介绍 bindValue 方法的基本概念、使用方式以及在实际开发中的应用。
1. bindValue 方法简介
bindValue 方法是 QSqlQuery 类的一个成员函数,用于将实际的数据值绑定到参数化 SQL 语句中的占位符。这种方法可以有效防止 SQL 注入攻击,是一种安全的数据操作实践。
2. 基本语法
bindValue 方法的基本语法如下:
bool QSqlQuery::bindValue(const QString &placeholder, const QVariant &val)
placeholder:SQL 语句中的占位符,通常是一个字符串。
val:要绑定的数据值,类型为 QVariant。
3. 参数化查询的优势
使用参数化查询有以下优势:
安全性:防止 SQL 注入攻击。
灵活性:可以轻松地替换和修改数据值。
性能:数据库可以缓存和重用参数化查询的执行计划。
4. 使用 bindValue 方法
在使用 bindValue 方法之前,通常需要先使用 prepare 方法准备一个参数化的 SQL 语句。以下是使用 bindValue 方法的基本步骤:
准备 SQL 语句:使用 prepare 方法准备 SQL 语句。
绑定值:使用 bindValue 方法将数据值绑定到 SQL 语句的占位符。
执行查询:使用 exec 方法执行 SQL 语句。
5. 示例代码
以下是一个使用 bindValue 方法的示例:
#include <QCoreApplication>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QDebug>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName("example.db");if (!db.open()) {qDebug() << "Error: Unable to open database";return 1;}QSqlQuery query;query.setDatabase(db);// 准备 SQL 语句query.prepare("INSERT INTO people (name, age) VALUES (:name, :age)");// 绑定值query.bindValue(":name", "John Doe");query.bindValue(":age", 30);// 执行查询if (query.exec()) {qDebug() << "Query executed successfully";} else {qDebug() << "Error:" << query.lastError().text();}return a.exec();
}
在这个示例中,我们准备了一个插入语句,并将两个参数 name 和 age 绑定到实际的数据值上。
6. 处理查询结果
对于查询操作,除了执行 SQL 语句外,还需要处理查询结果。以下是处理查询结果的步骤:
执行查询:使用 exec 方法执行 SQL 查询语句。
逐行读取结果:使用 next 方法逐行读取查询结果。
获取字段值:使用 value 方法获取每行的字段值。
7. 示例代码
以下是一个处理查询结果的示例:
#include <QCoreApplication>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QDebug>int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName("example.db");if (!db.open()) {qDebug() << "Error: Unable to open database";return 1;}QSqlQuery query;query.setDatabase(db);// 创建表query.exec("CREATE TABLE IF NOT EXISTS people (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)");// 插入数据query.exec("INSERT INTO people (name, age) VALUES ('John Doe', 30)");// 准备查询query.prepare("SELECT * FROM people WHERE name = :name");// 绑定参数query.bindValue(":name", "John Doe");// 执行查询if (query.exec()) {while (query.next()) {int id = query.value(0).toInt();QString name = query.value(1).toString();int age = query.value(2).toInt();qDebug() << "ID:" << id << "Name:" << name << "Age:" << age;}} else {qDebug() << "Error:" << query.lastError().text();}return a.exec();
}
8. 错误处理
在执行 SQL 语句时,可能会遇到各种错误。QSqlQuery 提供了一些方法来检查和处理这些错误:
if (!query.exec()) {qDebug() << "Error:" << query.lastError().text();
}
9. 事务处理
在处理数据库事务时,bindValue 方法同样可以发挥作用。通过准备和执行 SQL 语句,可以确保事务的一致性和完整性。以下是事务处理的示例:
QSqlQuery query;
query.setDatabase(db);query.startTransaction();
query.exec("INSERT INTO people (name, age) VALUES ('Alice', 25)");
query.exec("INSERT INTO people (name, age) VALUES ('Bob', 35)");
if (!query.commit()) {query.rollback();qDebug() << "Transaction failed:" << query.lastError().text();
}
相关文章:
qt 操作多个sqlite文件
qt 操作多个sqlite文件 Chapter1 qt 操作多个sqlite文件1. 引入必要的头文件2. 创建并连接多个SQLite数据库3. 代码说明4. 注意事项 Chapter2 qt 多线程操作sqlite多文件1. 引入必要的头文件2. 创建数据库操作的工作线程类3. 在主线程中创建并启动多个工作线程4. 代码说明5. 运…...

WSL with NVIDIA Container Toolkit
一、wsl 下安装 docker 会提示安装 docekr 桌面版,所以直接安装 docker 桌面版本即可 二、安装 NVIDIA Container Toolkit NVIDIA Container Toolkit仓库 https://github.com/NVIDIA/nvidia-container-toolkitgithub.com/NVIDIA/nvidia-container-toolkit 安装…...

Vue 系列之:组件通讯
子组件调用父组件方法 1、直接在子组件中通过 this.$parent.event 来调用父组件的方法 父组件: <template><p><child></child></p> </template> <script>import child from ./child;export default {components: {chi…...

【Linux实践系列】:用c语言实现一个shell外壳程序
🔥本文专栏:Linux Linux实践项目 🌸博主主页:努力努力再努力wz 那么今天我们就要进入Linux的实践环节,那么我们之前学习了进程控制相关的几个知识点,比如进程的终止以及进程的等待和进程的替换,…...
STL map 的 lower_bound(x)、upper_bound(x) 等常用函数
【STL map 简介】 ● STL map 是一种关联容器,存储键值对,每个键(key value)是唯一的,而值(mapped value)可以重复。构建 STL map 时,无论元素插入顺序如何,STL map 中的…...

【A2DP】SBC 编解码器互操作性要求详解
目录 一、SBC编解码器互操作性概述 二、编解码器特定信息元素(Codec Specific Information Elements) 2.1 采样频率(Sampling Frequency) 2.2 声道模式(Channel Mode) 2.3 块长度(Block Length) 2.4 子带数量(Subbands) 2.5 分配方法(Allocation Method) 2…...
Computational Linguistics期刊全解析:领域顶刊的投稿指南与学术价值
在人工智能与语言学交叉融合的浪潮中,《Computational Linguistics》(CL)作为该领域的标杆期刊,始终是研究者发表前沿成果的首选平台。本文将从期刊影响力、投稿策略、收稿方向等角度,为学者提供一份全面的指南。 一、…...
【量化科普】Sharpe Ratio,夏普比率
【量化科普】Sharpe Ratio,夏普比率 🚀量化软件开通 🚀量化实战教程 在量化投资领域,夏普比率(Sharpe Ratio)是一个非常重要的风险调整后收益指标。它由诺贝尔经济学奖得主威廉F夏普(William…...

运行OpenManus项目(使用Conda)
部署本项目需要具备一定的基础:Linux基础、需要安装好Anaconda/Miniforge(Python可以不装好,直接新建虚拟环境的时候装好即可),如果不装Anaconda或者Miniforge,只装过Python,需要确保Python是3.…...

TikTok Shop欧洲市场爆发,欧洲TikTok 运营网络专线成运营关键
TikTok在欧洲的影响力还在持续攀升,日前,TikTok发布了最新的欧盟执行和使用数据报告,报告中提到: 2024年7~12月期间,TikTok在欧盟地区的月活用户达1.591亿,较上一报告期(2024年10月发布…...

基于YOLO11深度学习的电瓶车进电梯检测与语音提示系统【python源码+Pyqt5界面+数据集+训练代码】
《------往期经典推荐------》 一、AI应用软件开发实战专栏【链接】 项目名称项目名称1.【人脸识别与管理系统开发】2.【车牌识别与自动收费管理系统开发】3.【手势识别系统开发】4.【人脸面部活体检测系统开发】5.【图片风格快速迁移软件开发】6.【人脸表表情识别系统】7.【…...

计算机毕业设计SpringBoot+Vue.js制造装备物联及生产管理ERP系统(源码+文档+PPT+讲解)
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...

微服务保护:Sentinel
home | Sentinelhttps://sentinelguard.io/zh-cn/ 微服务保护的方案有很多,比如: 请求限流 线程隔离 服务熔断 服务故障最重要原因,就是并发太高!解决了这个问题,就能避免大部分故障。当然,接口的并发…...
labelimg标注的xml标签转换为yolo格式标签
本文不生产技术,只做技术的搬运工!!! 前言 在yolo训练时,我们需要对图像进行标注,而使用labelimg标注时如果直接选择输出yolo格式的数据集,则原始数据的很多信息无法被保存,因此一版…...

VUE3开发-9、axios前后端跨域问题解决方案
VUE前端解决跨域问题 前端页面需要改写 如果无效,记得重启服务器 后端c#解决跨域问题 前端js取值,后端c#跨域_c# js跨域-CSDN博客...
机试准备第12天
首先学习队列,队列有先进先出的特性。广度优先遍历需要基于队列实现,C中的stl引入了队列的实现方式。队列支持push(),进入队尾,pop()出队,队头出队,front()获取队首元素,back()获取队尾元素&…...

计算机二级MS之PPT
声明:跟着大猫和小黑学习随便记下一些笔记供大家参考,二级考试之前将持续更新,希望大家二级都能轻轻松松过啦,过了二级的大神也可以在评论区留言给点建议,感谢大家!! 文章目录 考题难点1cm25px…...
伊藤积分(Ito Integral):随机世界中的积分魔法
伊藤积分(Ito Integral):随机世界中的积分魔法 在研究随机微分方程(SDE)和布朗运动时,伊藤积分(Ito Integral)是一个绕不开的关键概念。它是处理布朗运动随机项 ( d W ( t ) dW(t)…...

【Deepseek应用】Zotero+Deepseek 阅读和分析文献(下)
【Deepseek应用】Deepseek R1 本地部署(OllamaDockerOpenWebUI) 【Deepseek应用】ZoteroDeepseek 阅读和分析文献(上) 【Deepseek应用】ZoteroDeepseek 阅读和分析文献(下) 使用邀请码 cXfb9wOT 注册 硅基流…...
人工智能与深度学习的应用案例:从技术原理到实践创新
第一章 引言 人工智能(AI)作为21世纪最具变革性的技术之一,正通过深度学习(Deep Learning)等核心技术推动各行业的智能化进程。从计算机视觉到自然语言处理,从医疗诊断到工业制造,深度学习通过模拟人脑神经网络的层次化学习机制,实现了对复杂数据的高效分析与决策。本…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...

MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
浅谈不同二分算法的查找情况
二分算法原理比较简单,但是实际的算法模板却有很多,这一切都源于二分查找问题中的复杂情况和二分算法的边界处理,以下是博主对一些二分算法查找的情况分析。 需要说明的是,以下二分算法都是基于有序序列为升序有序的情况…...

企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...

【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...

LabVIEW双光子成像系统技术
双光子成像技术的核心特性 双光子成像通过双低能量光子协同激发机制,展现出显著的技术优势: 深层组织穿透能力:适用于活体组织深度成像 高分辨率观测性能:满足微观结构的精细研究需求 低光毒性特点:减少对样本的损伤…...