Qt中使用MySQL数据库

一、MySQL 入门

核心概念

在 QT 中操作数据库,主要使用两个模块:

  1. QSqlDatabase:代表一个数据库连接。

  2. QSqlQuery:用于执行 SQL 语句(如 SELECTINSERTUPDATEDELETE)并处理结果。

环境准备

在编写代码之前,你需要确保系统已具备以下条件:

1. 安装 MySQL
  • 从 MySQL 官网 下载并安装 MySQL 服务器和客户端。

  • 记住你设置的 root 密码,或者创建一个用于测试的新数据库用户。

2. 安装 QT
  • 确保你的 QT 安装包含了 Qt SQL 模块。在安装 QT 时,通常默认会包含。

3. 安装 MySQL 驱动(最关键的一步)

QT 默认可能不包含 MySQL 的驱动插件,你需要自己编译或确保它存在。

检查现有驱动:
你可以写一个简单的程序来查看当前可用的数据库驱动。

cpp

#include <QCoreApplication>
#include <QSqlDatabase>
#include <QDebug>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);qDebug() << "Available drivers:";QStringList drivers = QSqlDatabase::drivers();foreach(QString driver, drivers)qDebug() << driver;return 0;
}

如果输出中包含 "QMYSQL" 或 "QMYSQL3",说明驱动已安装。如果没有,你需要手动编译。

如何编译 MySQL 驱动?

  1. 找到 QT 的源码目录:确保你有 QT 的源代码。路径通常像 ~/Qt/5.15.2/Src (5.15.2 是版本号)。

  2. 找到驱动代码:进入 ~/Qt/5.15.2/Src/qtbase/src/plugins/sqldrivers/mysql

  3. 编译

    • Windows: 使用 Qt Creator 打开该目录下的 .pro 工程文件进行编译。你需要确保在项目的构建设置中指定 MySQL 的 include 和 lib 目录。

    • Linux (Ubuntu/Debian):

      bash

      # 安装 MySQL 开发文件
      sudo apt-get install libmysqlclient-dev# 进入驱动目录
      cd ~/Qt/5.15.2/Src/qtbase/src/plugins/sqldrivers# 使用 qmake 生成 Makefile,指定 MySQL 的路径(如果不在标准路径)
      qmake -- MYSQL_PREFIX=/usr/include/mysql # 或者你的 MySQL 安装路径
      make
      make install # 将编译好的插件复制到 QT 的插件目录
    • macOS (使用 Homebrew):

      bash

      # 安装 MySQL
      brew install mysql# 进入驱动目录
      cd ~/Qt/5.15.2/Src/qtbase/src/plugins/sqldrivers# 使用 qmake
      qmake "INCLUDEPATH+=/usr/local/opt/mysql/include" "LIBS+=-L/usr/local/opt/mysql/lib -lmysqlclient" mysql.pro
      make
      make install

编译成功后,生成的 libqsqlmysql.so (Linux), qsqlmysql.dll (Windows),或 libqsqlmysql.dylib (macOS) 文件会被复制到 QT 的插件目录(如 Qt/5.15.2/gcc_64/plugins/sqldrivers)。确保你的程序运行时能找到这个插件。

编写代码

假设我们已经有一个名为 test_db 的数据库,其中有一张表 users

sql

CREATE TABLE users (id INT PRIMARY KEY AUTO_INCREMENT,name VARCHAR(100) NOT NULL,email VARCHAR(100) NOT NULL
);
步骤 1:项目配置 (.pro 文件)

在你的 QT 项目文件 (.pro) 中,添加 sql 模块。

pro

QT += core gui sql # 添加 sql 模块
步骤 2:C++ 代码实现

以下是完整的示例代码,包含连接数据库、插入、查询、更新和删除操作。

cpp

#include <QCoreApplication>
#include <QtSql> // 包含所有 SQL 相关的头文件
#include <QDebug>int main(int argc, char *argv[])
{QCoreApplication a(argc, argv);// 1. 建立并打开数据库连接QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL"); // 指定数据库类型db.setHostName("localhost");      // 数据库服务器 IP,本地则为 localhostdb.setPort(3306);                // 端口号,默认 3306db.setDatabaseName("test_db");    // 要连接的数据库名db.setUserName("root");           // 数据库用户名db.setPassword("your_password"); // 数据库密码if (!db.open()) {qDebug() << "Failed to connect to database:" << db.lastError().text();return -1;} else {qDebug() << "Database connected successfully!";}// 2. 执行 SQL 语句 (使用 QSqlQuery)QSqlQuery query;// --- INSERT 示例 ---query.prepare("INSERT INTO users (name, email) VALUES (:name, :email)");query.bindValue(":name", "Alice");query.bindValue(":email", "alice@example.com");if (!query.exec()) {qDebug() << "Insert failed:" << query.lastError().text();} else {qDebug() << "Insert successful!";}// --- SELECT 示例 ---if (!query.exec("SELECT id, name, email FROM users")) {qDebug() << "Select failed:" << query.lastError().text();} else {qDebug() << "\nQuery results:";while (query.next()) { // 遍历结果集int id = query.value(0).toInt();        // 通过索引获取字段QString name = query.value("name").toString(); // 通过字段名获取QString email = query.value(2).toString();     // 通过索引获取字段qDebug() << "ID:" << id << "Name:" << name << "Email:" << email;}}// --- UPDATE 示例 ---query.prepare("UPDATE users SET email = ? WHERE name = ?");query.addBindValue("new_alice@example.com"); // 绑定第一个问号的值query.addBindValue("Alice");                // 绑定第二个问号的值if (!query.exec()) {qDebug() << "Update failed:" << query.lastError().text();}// --- DELETE 示例 ---query.prepare("DELETE FROM users WHERE name = :name");query.bindValue(":name", "Alice");if (!query.exec()) {qDebug() << "Delete failed:" << query.lastError().text();}// 3. 关闭数据库连接 (可选,程序结束时会自动关闭)db.close();return 0; // return a.exec(); 如果是 GUI 应用
}
代码详解
  • QSqlDatabase::addDatabase(“QMYSQL”): 创建一个 MySQL 类型的数据库连接。"QMYSQL" 是驱动的名称。

  • setHostName(), setDatabaseName(), ...: 设置连接数据库所需的参数。

  • db.open(): 尝试连接数据库。如果失败,可以通过 db.lastError() 获取错误信息。

  • QSqlQuery: 用于执行 SQL 语句的核心类。

  • query.prepare() + query.bindValue()推荐使用 的预处理语句方式。它可以防止 SQL 注入攻击,并且更高效。:name 是命名占位符,? 是位置占位符。

  • query.exec(): 执行 SQL 语句。对于 SELECT 语句,它会返回一个结果集。

  • query.next(): 遍历结果集中的每一条记录。初始时,指针位于第一条记录之前。

  • query.value(): 获取当前记录中某个字段的值。可以通过数字索引(从 0 开始)或字段名称的字符串来访问。

高级主题 - 模型/视图编程

QT 提供了更高级的 QSqlTableModel 和 QSqlQueryModel,可以将数据库中的数据直接与 QTableView 等视图组件绑定,实现数据的自动显示和编辑。

示例:使用 QSqlTableModel 在表格视图中显示数据

cpp

#include <QApplication>
#include <QTableView>
#include <QSqlTableModel>
#include <QSqlDatabase>
#include <QSqlError>int main(int argc, char *argv[]) {QApplication app(argc, argv);// ... (数据库连接代码,同上) ...// 创建模型并设置表QSqlTableModel *model = new QSqlTableModel;model->setTable("users");model->setEditStrategy(QSqlTableModel::OnManualSubmit); // 设置编辑策略model->select(); // 从数据库获取数据// 创建视图并设置模型QTableView *view = new QTableView;view->setModel(model);view->show();return app.exec();
}

常见错误与调试

  1. QSqlDatabase: QMYSQL driver not loaded

    • 原因:MySQL 驱动未正确安装或部署。

    • 解决:按照本指南第一部分的步骤编译驱动,并确保生成的驱动文件在程序的运行时可访问路径下(通常是程序所在目录的 sqldrivers 子文件夹,或者 QT 安装目录的 plugins/sqldrivers 文件夹)。

  2. Unknown database ‘test_db’

    • 原因:MySQL 中不存在该数据库。

    • 解决:先用 MySQL 客户端(如命令行或 Workbench)创建数据库。

  3. Access denied for user ‘root’@‘localhost’

    • 原因:用户名或密码错误,或者该用户没有从本地主机连接的权限。

    • 解决:检查登录凭据,或在 MySQL 中为用户授权。

  4. Can’t connect to MySQL server on ‘localhost’ (10061)

    • 原因:MySQL 服务没有启动。

    • 解决:去服务管理器中启动 MySQL 服务。

调试技巧

  • 始终检查 open() 和 exec() 的返回值

  • 使用 lastError().text() 来获取人类可读的错误信息。这是你最好的朋友!

二、MySQL 数据类型

核心关系对应表

MySQL 数据类型 推荐 / 对应的 C++ 类型 Qt 中常用的读取方法 (从 QSqlQuery 或 QSqlRecord) Qt 中常用的写入方法 (到 QSqlQuery 预处理语句) 注意事项
整数类型
TINYINT int / bool .toInt() / .toBool() :value 绑定 int / bool TINYINT(1) 通常被视为布尔值。
SMALLINT int .toInt() :value 绑定 int
MEDIUMINT int .toInt() :value 绑定 int
INT / INTEGER int .toInt() :value 绑定 int
BIGINT qint64 .toLongLong() :value 绑定 qint64 确保编译器支持 64 位整数。
浮点数类型
FLOAT float .toFloat() :value 绑定 float 可能存在精度问题。
DOUBLE / REAL double .toDouble() :value 绑定 double
DECIMAL(M, D) QString .toString() :value 绑定 QString 最佳实践:为避免浮点精度损失,金额等精确数值建议用 QString 读取。也可以用 .toDouble() 但需谨慎。
字符串类型
CHAR(N) QString .toString() :value 绑定 QString Qt 会自动处理编码转换(通常使用 UTF-8)。
VARCHAR(N) QString .toString() :value 绑定 QString
TINYTEXT QString .toString() :value 绑定 QString
TEXT QString .toString() :value 绑定 QString 对于非常大的文本,确保有足够的内存。
BLOB QByteArray .toByteArray() :value 绑定 QByteArray 用于存储二进制数据,如图片、文件等。
LONGTEXT QString .toString() :value 绑定 QString
LONGBLOB QByteArray .toByteArray() :value 绑定 QByteArray
日期时间类型
DATE QDate .toDate() :value 绑定 QDate MySQL 的日期格式与 QDate 兼容。
TIME QTime .toTime() :value 绑定 QTime
DATETIME QDateTime .toDateTime() :value 绑定 QDateTime 注意:MySQL 5.6.4+ 支持小数秒,但 QDateTime 不直接支持,读取时会被截断。
TIMESTAMP QDateTime .toDateTime() :value 绑定 QDateTime 存储的是 UTC 时间,读取时 Qt 会将其转换为本地时间。写入时,Qt 会将本地时间转换为 UTC 存储。行为需确认
其他类型
ENUM('val1', 'val2') QString .toString() :value 绑定 QString 读取其字符串值。
SET('val1', 'val2') QString .toString() :value 绑定 QString 读取逗号分隔的字符串集合。
BOOL / BOOLEAN bool .toBool() :value 绑定 bool 本质上是 TINYINT(1) 的别名。
JSON (MySQL 5.7.8+) QString .toString() :value 绑定 QString 在 Qt 中作为字符串处理,解析可使用 QJsonDocument

如何使用:代码示例

1. 读取数据 (SELECT)

cpp

QSqlQuery query;
query.exec("SELECT id, name, salary, birth_date FROM employees");while (query.next()) {// 通过字段索引读取 (从0开始)int id = query.value(0).toInt(); // 通过字段名读取 (更安全可靠)QString name = query.value("name").toString();double salary = query.value("salary").toDouble(); // 注意DECIMAL的精度问题QDate birthDate = query.value("birth_date").toDate();qDebug() << "ID:" << id << "Name:" << name << "Salary:" << salary << "Birth Date:" << birthDate.toString(Qt::ISODate);
}
2. 写入数据 (INSERT / UPDATE) - 使用预处理语句(推荐,可防SQL注入

cpp

QSqlQuery query;
// 使用命名占位符
query.prepare("INSERT INTO employees (name, salary, hire_date, avatar) ""VALUES (:name, :salary, :hire_date, :avatar)");// 将C++/Qt类型的值绑定到占位符
query.bindValue(":name", "John Doe");
query.bindValue(":salary", 75000.50);
query.bindValue(":hire_date", QDate::currentDate()); // 绑定QDate// 插入BLOB数据(例如图片)
QFile file("avatar.png");
if (file.open(QIODevice::ReadOnly)) {QByteArray imageData = file.readAll();query.bindValue(":avatar", imageData); // 绑定QByteArray
} else {query.bindValue(":avatar", QVariant(QVariant::ByteArray)); // 绑定空值
}// 执行查询
if (

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

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

相关文章

Android - 统一资源标识符 Uri

一、概念URI&#xff08;Uniform Resource Identifier&#xff09;统一资源标识符&#xff0c;用于标识资源的字符串&#xff08;如图片、网页、文件、应用等&#xff09;。1.1 与 URL 的区别URL&#xff08;统一资源定位符&#xff09;是 URI&#xff08;统一资源标识符&#…

开源 AR 眼镜怎么选?OpenGlass ,OSSG,cheApR 分析推荐

开源项目横评&#xff08;看完你会知道自己属于哪一类&#xff09; 1&#xff09;OpenGlass&#xff1a;最低成本跑通“能用的AI眼镜” 卖点&#xff1a;用不到$25的通用元件&#xff0c;把任意普通眼镜改造成“可黑客化”的智能眼镜&#xff1b;能录制、识别、翻译、记人等。…

RAGFlow (一) 开发环境搭建

本文介绍如何在Windows上进行RAGFlow开发环境搭建 一. 环境准备 前提条件 CPU ≥ 4 核内存 ≥ 16 GB磁盘 ≥ 50 GBDocker ≥ 24.0.0 & Docker Compose ≥ v2.26.1 安装Docker Desktop为wsl安装Ubuntu 1.启用 WSL2​​&#xff08;Windows Subsystem for Linux&#xff09…

k8sday13数据存储(1.5/2)

目录 二、高级核心存储 1、PV 1.1配置文件 ①、访问模式&#xff08;accessModes&#xff09; ②、回收策略&#xff08;persistentVolumeReclaimPolicy&#xff09; ③、存储类别 ④、状态&#xff08;Status&#xff09; 1.2创建测试 ①、准备NFS环境 ②、创建PV …

【力扣 Hot100】每日一题

D15 鲁迅曾说&#xff0c;尽量每天都让自己充实一点&#xff0c;你可以刷一个小时的短视频&#xff0c;打一个小时的王者荣耀&#xff0c;但尽量再留一个小时出来读一下书、教程、博客&#xff0c;让自己的大脑保持活跃&#xff0c;而不是垃圾场。如果真的没有事情做&#xff…

Sql server的行转列

业务场景&#xff1a;有如下一张表&#xff0c;希望汇总成下面的查询结果。 原始数据表 EmployeeTable&#xff1a;一个员工身兼多个岗位。 Employee Role Level 张三 工程师 3 张三 经理 5 李四 工程师 2 李四 主管…

某市-2025【网安·论道】决赛-misc1-翻转-wp

题目给了个图片以及一句提示 “斯蒂xx会帮助你” 直接就能想到 ste 开头的那几个工具&#xff0c;但是我比赛时候电脑什么ste开头的工具都没装&#xff0c;只能回来做了。 └─$ exiftool x.jpeg ExifTool Version Number : 13.00 File Name : …

[系统架构设计师]大数据架构设计理论与实践(十九)

[系统架构设计师]大数据架构设计理论与实践&#xff08;十九&#xff09; 一.传统数据处理系统的问题 1.传统数据库的数据过载问题 传统应用的数据系统架构设计时&#xff0c;应用直接访问数据库系统。当用户访问量增加时&#xff0c;数据库无 法支撑日益增长的用户请求的负载&…

UniAD

1. 算法动机及开创性思路 1&#xff09;UniAD算法简介 算法全称&#xff1a;Planning-oriented Autonomous Driving核心特点&#xff1a; 统一框架整合感知、预测、规划模块CVPR 2023最佳论文采用查询(query)方式连接各模块 名称含义&#xff1a; Unified&#xff1a;统一多模块…

ESP-NOW详解(esp-idf)

esp-now目前主要支持单播和广播&#xff0c;广播地址为ff:ff:ff:ff:ff:ff,广播可以向范围内所有拥有esp-now接收的设备发送数据 注意事项&#xff0c;网络模式是可以设置网络mac地址的&#xff0c;在单播中&#xff0c;目标设备网络模式选择为ap时&#xff0c;mac地址会发生改…

`strlen` 字符串长度函数

1) 函数的概念与用途 strlen 是 C 语言标准库中最基础且使用最频繁的字符串处理函数之一&#xff0c;它的名字来源于"string length"&#xff08;字符串长度&#xff09;。这个函数的功能非常明确&#xff1a;计算一个以空字符结尾的字符串的长度。 可以将 strlen 想…

TorchInductor - Introduction

PyTorch 2.x通过TorchDynamo通过Python Bytecode的动态变换实现了图捕获功能&#xff0c;需要搭配一个Compiler Backend完成图编译。 Pytorch尝试集成了多个后端&#xff0c;并使用一个轻量级的autotuner来选择最优的后端图编译结果。这个解决方案存在2个问题&#xff1a; 这…

Adobe Illustrator默认键盘快捷键

目录 默认键盘快捷键 常用的快捷键 处理文档 选择工具 查看图稿 处理所选对象 绘制 编辑形状 处理实时上色组 处理对象 创建可变宽度点 处理文字 使用面板 动作面板 “画笔”面板 “字符”和“段落”面板 “颜色”面板 “渐变”面板 “图层”面板 “色板”…

「数据获取」《中国能源统计年鉴》(1986-2023)(获取方式看绑定的资源)

01、数据简介一、年鉴基本定位与发展历程《中国能源统计年鉴》作为一部权威性极强的能源领域资料典籍&#xff0c;始终以全面、精准反映中国能源建设推进、生产运行、消费态势以及供需平衡状况为核心使命。其编纂工作发轫于 1986 年&#xff0c;最初由国家统计局工业交通统计司…

SpringBoot3系列---【SpringBoot3集成sqlite】

SpringBoot3集成sqlite 1.引入pom.xml <dependencies><dependency><groupId>org.xerial</groupId><artifactId>sqlite-jdbc</artifactId><version>3.34.0</version></dependency><dependency><groupId>com.…

头部 TTS 开源项目深度对比

语音合成&#xff08;TTS&#xff09;开源项目是技术研究与产业落地的核心支撑&#xff0c;不同项目因技术路线、设计目标差异&#xff0c;在语言覆盖、合成自然度、可扩展性等方面表现悬殊。本文选取当前开源生态中应用最广、影响力最大的五大 TTS 项目——MaryTTS、Coqui TTS…

可视化-模块1-HTML-02

1-新建一个HTML文档&#xff0c;命名为&#xff1a;week1-12-<h1>标签<body><h1>这是标题 1</h1> <h2>这是标题 2</h2> <h3>这是标题 3</h3> <h4>这是标题 4</h4> <h5>这是标题 5</h5> <h6>这是…

搜索算法在实际场景中的应用

1. 数据库系统 B+树索引 应用场景:关系型数据库(MySQL、PostgreSQL等)的索引实现 算法特点: 平衡多路搜索树,优化磁盘I/O 支持范围查询和排序操作 典型实现: CREATE INDEX idx_name ON users(last_name); 哈希索引 应用场景:键值存储(Redis、Memcached)、等值查询 算…

基础IO

目录 一、进程和文件的关系 二、背景补充 三、打开文件接口 (1) FILE *fopen(const char* filename , const char *mode) &#xff08;2&#xff09;open 系统调用 文件描述符 open和fopen的关系 &#xff08;3&#xff09;size_t fwrite&#xff08;const void * ptr, …

SpringBoot快速上手

SpringBoot快速上手 环境准备 IDEA版本: 社区版:2021.1-2022.1.4 专业版:无要求 Maven 官方对于Maven的描述: Maven是一个项目管理工具,基于POM(Project Object Model,项目对象模型)的概念,Maven可以通过一小段描述信息来管理项目的构建,报告文档和项目管理工具软件. 人…