详解Qt中访问数据库

在Qt中访问数据库涉及到几个关键步骤,主要包括加载数据库驱动、建立数据库连接、执行SQL语句、读取结果等。下面将详细介绍这些步骤,并给出一个简单的示例,这里假设使用的是SQLite数据库。
记得首先在pro文件中添加QT += sql

1. 加载数据库驱动

Qt通过数据库驱动程序来支持不同类型的数据库,例如SQLite、MySQL、PostgreSQL等。在实际使用前,通常需要确保已经包含了相应的数据库驱动模块。对于SQLite,由于Qt内置了对其的支持,无需额外安装驱动。

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>// 如果使用其他数据库,可能需要包含对应的头文件,例如:
// #include <QMYSQLDriver> // 对于MySQL
// #include <QPSQLDriver> // 对于PostgreSQL

注意: 当前Qt是否已经安装将要使用的数据库驱动,可以使用QSqlDatabase::drivers()去查看

#include <QtSql>  
#include <QDebug>  int main(int argc, char *argv[]) {  QCoreApplication a(argc, argv);  //输出所有已经支持的数据库驱动QStringList drivers = QSqlDatabase::drivers();  foreach (const QString &driver, drivers) {  qDebug() << driver;  }  return a.exec();  
}

2. 创建数据库连接

创建数据库连接通常涉及指定数据库类型(如果是SQLite,则通常不需要用户名、密码和数据库地址,因为SQLite数据库文件是本地文件)。

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE"); // 对于SQLite
// 或者
// QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); // 对于MySQL
// QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL"); // 对于PostgreSQLdb.setHostName("localhost"); // 对于远程数据库,设置主机名或IP
db.setDatabaseName("/path/to/mydatabase.db"); // 对于SQLite,这是数据库文件路径;对于其他数据库则是数据库名
db.setUserName("username"); // 非SQLite数据库的用户名
db.setPassword("password"); // 非SQLite数据库的密码if (!db.open()) {qDebug() << "Failed to connect to database: " << db.lastError().text();return false; // 连接失败
}

3. 执行SQL查询或命令

使用QSqlQuery类执行SQL语句。

QSqlQuery query;// 插入数据
query.prepare("INSERT INTO MyTable (column1, column2) VALUES (?, ?)");
query.addBindValue(value1);
query.addBindValue(value2);
if (!query.exec()) {qDebug() << "Insert error: " << query.lastError().text();
} else {qDebug() << "Row inserted successfully.";
}// 查询数据
query.clear();
query.prepare("SELECT * FROM MyTable WHERE id = ?");
query.bindValue(0, someId);
if (query.exec()) {while (query.next()) {QString value1 = query.value(0).toString();int value2 = query.value(1).toInt();// ... 处理查询结果 ...}
} else {qDebug() << "Select error: " << query.lastError().text();
}

4. 关闭数据库连接

在完成所有数据库操作后,关闭连接以释放资源。

db.close();

示例完整代码片段

#include <QCoreApplication>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");db.setDatabaseName(":memory:"); // 使用内存数据库,也可以替换为实际文件路径if (!db.open()) {qDebug() << "Cannot open database: " << db.lastError().text();return 1;}// 创建表QSqlQuery createQuery;createQuery.exec("CREATE TABLE IF NOT EXISTS MyTable (id INTEGER PRIMARY KEY, column1 VARCHAR(40), column2 INT)");// 插入数据QSqlQuery insertQuery;insertQuery.prepare("INSERT INTO MyTable (column1, column2) VALUES (?, ?)");insertQuery.addBindValue("Example Value");insertQuery.addBindValue(123);if (!insertQuery.exec()) {qDebug() << "Insert error: " << insertQuery.lastError().text();} else {qDebug() << "Row inserted successfully.";}// 查询数据QSqlQuery selectQuery;selectQuery.prepare("SELECT * FROM MyTable");if (selectQuery.exec()) {while (selectQuery.next()) {QString column1Value = selectQuery.value(1).toString();int column2Value = selectQuery.value(2).toInt();qDebug() << "Column1: " << column1Value << ", Column2: " << column2Value;}} else {qDebug() << "Select error: " << selectQuery.lastError().text();}db.close();return a.exec();
}

以上代码演示了如何使用Qt连接SQLite数据库,执行创建表、插入数据和查询数据的操作。
注意

  1. 对于不同的数据库类型,配置连接参数的方式会有所不同,但执行SQL的基本模式是相似的。
  2. 上述代码中使用的Sqlite数据库的内存模式。访问速度非常快。适合作为临时的缓存数据库使用。

打开多个数据库

在Qt程序中同时打开和操作多个数据库,可以通过创建多个QSqlDatabase实例来实现。每个数据库实例都有自己的名字(connection name),这样可以区分不同数据库连接。以下是一个简单的示例,展示如何同时打开两个SQLite数据库:

#include <QApplication>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QDebug>int main(int argc, char *argv[])
{QApplication a(argc, argv);// 打开第一个SQLite数据库QSqlDatabase db1 = QSqlDatabase::addDatabase("QSQLITE");db1.setDatabaseName("first_db.sqlite");if (!db1.open()) {qDebug() << "Failed to open the first database: " << db1.lastError().text();return 1;}// 执行第一个数据库的查询QSqlQuery query1(db1);query1.exec("CREATE TABLE IF NOT EXISTS Table1 (ID INTEGER PRIMARY KEY, Name TEXT)");if (!query1.isActive())qDebug() << "Error creating table in first DB: " << query1.lastError().text();// 打开第二个SQLite数据库QSqlDatabase db2 = QSqlDatabase::addDatabase("QSQLITE");db2.setDatabaseName("second_db.sqlite");if (!db2.open()) {qDebug() << "Failed to open the second database: " << db2.lastError().text();db1.close();return 1;}// 执行第二个数据库的查询QSqlQuery query2(db2);query2.exec("CREATE TABLE IF NOT EXISTS Table2 (ID INTEGER PRIMARY KEY, Name TEXT)");if (!query2.isActive())qDebug() << "Error creating table in second DB: " << query2.lastError().text();// 不论操作成功与否,记得在不再使用时关闭数据库连接db1.close();db2.close();return a.exec();
}

在上述示例中,我们创建了两个不同的SQLite数据库连接,并分别为它们创建了表。当然,你可以根据需要连接不同类型(如MySQL、PostgreSQL等)的数据库,只需在调用addDatabase时指定正确的数据库驱动名称即可。

务必注意,当在多线程环境中操作数据库时,即使Qt的数据库模块是线程安全的,也应该确保在同一时刻仅在一个线程中操作单个数据库连接,或者正确地管理线程间的同步,防止数据竞争问题。同时,也要确保在不再需要时关闭数据库连接,以避免资源泄露。

使用建议

  1. 数据库处理通常在主线程,如果必要在其他线程中访问数据库,切记在哪个线程访问数据库就在哪个线程中打开数据库。
  2. 如果甲方对数据库没有硬性要求,建议使用sqlite。
  3. 在连接远程数据库进行查询数据的时候,如果遇到访问缓慢情况,建议开启QSqlQuery setForwardOnly(true)。可以看到奇迹的发生。

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

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

相关文章

#SOP#-如何使用AI辅助论文创作

#SOP#-如何使用AI辅助论文创作 ——2024.4.6 “在使用工具的时候&#xff0c;要做工具的主人” 最终交付物&#xff1a; 一份可执行的AI辅助创作论文的指导手册 交付物质量要求&#xff1a; 不为任何AI大模型付费&#xff01;不为任何降重网站付费&#xff01;通过知网检查论…

语义分割——自动驾驶鱼眼数据集

一、重要性及意义 环境感知&#xff1a;语义分割技术能够精确识别道路、车辆、行人、障碍物、交通标志和信号等各种交通场景元素。这为自动驾驶系统提供了丰富的环境信息&#xff0c;有助于车辆准确理解周围环境的结构和动态变化。决策规划&#xff1a;基于语义分割的结果&…

2024 最新版 Proteus 8.17 安装汉化教程

前言 大家好&#xff0c;我是梁国庆。 今天给大家带来的是目前 Proteus 的最新版本——Proteus 8.17。 时间&#xff1a;2024年4月4日 获取 Proteus 安装包 我已将本篇所使用的安装包打包上传至百度云&#xff0c;扫描下方二维码关注「main工作室」&#xff0c;后台回复【…

(2024,手部生成,SMPL,MANO,SD,手部参数)HanDiffuser:具有逼真手部外观的文本到图像生成

HanDiffuser: Text-to-Image Generation With Realistic Hand Appearances 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 2. 相关工作 3. HanDiffuser 3.1. 基础 3.2. Tex…

webrtcP2P通话流程

文章目录 webrtcP2P通话流程webrtc多对多 mesh方案webrtc多对多 mcu方案webrtc多对多 sfu方案webrtc案例测试getUserMediagetUserMedia基础示例-打开摄像头getUserMedia canvas - 截图 打开共享屏幕 webrtcP2P通话流程 在这里&#xff0c;stun服务器包括stun服务和turn转发服…

docker进行jenkins接口自动化测试持续集成实战

文章目录 一、接口功能自动化测试项目源码讲解二、接口功能自动化测试运行环境配置1、下载jdk&#xff0c;maven&#xff0c;git&#xff0c;allure并配置对应的环境变量2、使用docker安装jenkins3、配置接口测试的运行时环境选择对应节点4、jenkins下载插件5、jenkins配置环境…

VTK的交互器

VTK中鼠标消息是在交互类型对象&#xff08;interactorstyle&#xff09;中响应&#xff0c;因此通过为交互类型对象&#xff08;interactorstyle&#xff09;添加观察者&#xff08;observer&#xff09;来监听相应的消息&#xff0c;当消息触发时&#xff0c;由命令模式执行相…

浅谈Yum 安装和 源码安装

浅谈Yum 安装和 源码安装 本文所叙述的Linux系统是基于RedHat发行版的CentOS7 yum安装 1. 前言 我们知道在Windows上下载的安装包后缀是 .exe &#xff0c;与之对应的 在 Linux下的安装包的后缀是 .rpm rpm (Red Hat Package Manager) 是红帽软件包管理器 我们在Windows电脑…

I2C驱动实验:验证所添加的I2C设备的设备节点

一. 简介 前面一篇文章向设备树中的 I2C1控制器节点下&#xff0c;添加了AP3216C设备节点。文章如下&#xff1a; I2C驱动实验&#xff1a;向设备树添加 I2C设备的设备节点信息-CSDN博客 本文对设备树进行测试&#xff0c;确认设备节点是否成功创建好。 二. I2C驱动实验&a…

算法刷题应用知识补充--基础算法、数据结构篇

这里写目录标题 位运算&#xff08;均是拷贝运算&#xff0c;不会影响原数据&#xff0c;这点要注意&#xff09;&、|、^位运算特性细节知识补充对于n-1的理解异或来实现数字交换找到只出现一次的数据&#xff0c;其余数据出现偶数次 >> 、<<二进制中相邻的位的…

日志打印的学习之log4j2(一)最简单的案例

spring框架 首先引入依赖 <dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.11.1</version></dependency> 其次在resources下新增log4j2.xml文件 <?xml versio…

动态多目标优化:动态约束多目标优化测试集DCP1-DCP9的TruePF(提供MATLAB代码)

一、进化动态约束多目标优化测试集DCP1-DCP9 参考文献&#xff1a; [1]G. Chen, Y. Guo, Y. Wang, J. Liang, D. Gong and S. Yang, “Evolutionary Dynamic Constrained Multiobjective Optimization: Test Suite and Algorithm,” in IEEE Transactions on Evolutionary Com…

Web3:数字化社会的下一步

随着技术的不断进步和互联网的发展&#xff0c;我们正逐渐迈入一个全新的数字化社会阶段。在这个新的时代&#xff0c;Web3作为数字化社会的重要组成部分&#xff0c;将发挥着举足轻重的作用。本文将探讨Web3在数字化社会中的意义、特点以及对未来发展的影响。 1. 重新定义数字…

Django--数据库连接

数据库配置 打开mysite/settings.py配置文件&#xff0c;这是整个Django项目的设置中心。Django默认使用SQLite3数据库&#xff0c;因为Python原生支持SQLite3数据库&#xff0c;所以你无须安装任何程序&#xff0c;就可以直接使用它。 下面是默认的数据库配置&#xff1a; …

洛谷刷题 前缀和与差分-[P2004]领地选择(C++)

题目描述 作为在虚拟世界里统帅千军万马的领袖&#xff0c;小 Z 认为天时、地利、人和三者是缺一不可的&#xff0c;所以&#xff0c;谨慎地选择首都的位置对于小 Z 来说是非常重要的。 首都被认为是一个占地 CC 的正方形。小 Z 希望你寻找到一个合适的位置&#xff0c;使得首…

人脸识别:Arcface--loss+code

之前只接触过传统方法的人脸识别算法&#xff0c;本以为基于深度学习的方法会使用对比损失之类的函数进行训练&#xff0c;但是Arcface算法基于softmax进行了创新&#xff0c;本文未深究其详细的loss公式原理&#xff0c;在大致明白其方向下&#xff0c;运行了代码&#xff0c;…

06-kafka及异步通知文章上下架

kafka及异步通知文章上下架 1)自媒体文章上下架 需求分析 2)kafka概述 消息中间件对比 特性ActiveMQRabbitMQRocketMQKafka开发语言javaerlangjavascala单机吞吐量万级万级10万级100万级时效性msusmsms级以内可用性高&#xff08;主从&#xff09;高&#xff08;主从&#…

spring中各种bean加载顺序

具体加载顺序按照罗列的顺序 XXXAware ApplicationContextAware、EnvironmentAware、BeanFactoryAware、BeanClassLoaderAware 顾名思义&#xff0c;用于获取对应的对象&#xff0c;需要在实体类中声明对应的对象且当前类为普通类能被注入。 InitializingBean void afterProp…

pyaudio webrtcvad实现实时录制语音加VAD检测没人说话自动停止录制

vad检测没人说话超过2秒就自动停止录制并保存前面有人说话的音频文件 pip install webrtcvad代码: import pyaudio import wave import time import webrtcvadCHUNK = 320 # 20ms 的语音帧 FORMAT = pyaudio.paInt16 CHANNELS = 1 RATE = 16000 WAVE_OUTPUT_FILENAME

【leetcode面试经典150题】7.买卖股票的最佳时机(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…