> 技术文档 > Qt从入门到入土(十一) -数据库操作--MySQL_qt mysql

Qt从入门到入土(十一) -数据库操作--MySQL_qt mysql


引言

在Qt6使用MySQL前需要先安装MySQL驱动,详情请看本篇文章Qt6配置MySQL数据库(一文全搞定)-CSDN博客

安装配置好MySQL之后,就可以继续完成接下来的操作了。

MYSQL和SQLITE的区别

MYSQL SQLITE 数据存储在服务器上,通过网络与客户端通信 数据存储在本地的单个磁盘文件中,无需服务器进程 需要安装服务器软件,配置较为复杂

部署简单,只需将数据库文件复制到目标位置即可 

Qt使用时需要手动编译驱动

直接使用Qt sql模块

MySQL数据库常用命令

以下是一些常用的 MySQL 命令行操作:

  • 显示所有数据库

SHOW DATABASES;

  • 选择数据库

USE database_name;

  • 显示当前数据库中的表

SHOW TABLES;

  • 创建数据库

CREATE DATABASE database_name;

  • 创建表

CREATE TABLE students(num INTEGER PRIMARY KEY,name TEXT NOT NULL,age INTEGER,sex TEXT NOT NULL);

  • 插入数据

INSERT INTO students (num,name,age,sex) VALUES (1001,\"张三\",18,\"男\");

  • 查询数据

SELECT * FROM table_name;

  • 更新数据

UPDATE table_name SET column1 = value1, column2 = value2 WHERE condition;

  • 删除数据

DELETE FROM table_name WHERE condition;

  • 删除表

DROP TABLE table_name;

  • 退出 MySQL 命令行客户端

EXIT;

导入数据库模块

在CMakeLists.txt文件中加入以下指令,其中D:/mysql-9.2.0-winx64/include需要改成自己的目录

 

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets Sql)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets Sql)

 

include_directories(\"D:/mysql-9.2.0-winx64/include\")
link_directories(\"D:/mysql-9.2.0-winx64/lib\")

 

target_link_libraries(testMySQL PRIVATE Qt${QT_VERSION_MAJOR}::Widgets Qt${QT_VERSION_MAJOR}::Sql)

 如果使用qmake编译,则在.pro文件中加入以下代码

QT += core gui sql

INCLUDEPATH += \"D:/mysql-9.2.0-winx64/include\"
LIBS += -L\"D:/mysql-9.2.0-winx64/lib\" -llibmysql  

连接数据库

    // 添加 MySQL 数据库驱动
    QSqlDatabase db = QSqlDatabase::addDatabase(\"QMYSQL\");

    // 设置数据库连接参数
    db.setHostName(\"localhost\");  // 数据库服务器地址
    db.setDatabaseName(\"studentManagerSystem\"); // 数据库名称(连接指定数据库)
    db.setPort(3306);             // 设置端口号(默认是3306)
    db.setUserName(\"root\");       // 数据库用户名
    db.setPassword(\"12345678\");     // 数据库密码

    // 打开数据库连接
    if (!db.open())

    {
        qDebug() << \"Failed to connect to MySQL server:\" << db.lastError().text();
        return -1;
    }

    qDebug()<<\"Open database success!\";

创建新的数据库

    // 创建一个新的数据库
    QSqlQuery query;
    if (query.exec(\"CREATE DATABASE studentManagerSystem\"))

    {
        qDebug() << \"Database \'studentManagerSystem\' created successfully!\";
     } 

    else

    {
        qDebug() << \"Failed to create database \'studentManagerSystem\':\" << query.lastError().text();
     }

其他操作

MySQL和SQLite语法和基本操作类似,想了解数据库操作的可以参考此文章Qt从入门到入土(十) -数据库操作--SQLITE_qt 数据库-CSDN博客

数据库操作部分代码

//打印Qt支持的数据库驱动 qDebug() << QSqlDatabase::drivers(); // 添加 MySQL 数据库驱动 QSqlDatabase db = QSqlDatabase::addDatabase(\"QMYSQL\"); // 设置数据库连接参数 db.setHostName(\"localhost\"); // 数据库服务器地址 db.setDatabaseName(\"studentManagerSystem\"); // 数据库名称(连接指定数据库) db.setPort(3306); // 设置端口号(默认是3306) db.setUserName(\"root\"); // 数据库用户名 db.setPassword(\"12345678\"); // 数据库密码 // 打开数据库连接 if (!db.open()) { qDebug() << \"Failed to connect to MySQL server:\" << db.lastError().text(); return -1; } qDebug()<<\"Open database success!\"; QSqlQuery query(db); // 删除表 if(!query.exec(\"DROP TABLE IF EXISTS user;\")) { qDebug()<<\"删除失败!\"<<query.lastError();; return -1; } else { qDebug()<<\"删除成功!\"; } // 创建表 if(!query.exec(\"CREATE TABLE IF NOT EXISTS students(id INT PRIMARY KEY AUTO_INCREMENT,name TEXT NOT NULL,age INTEGER);\")) { qDebug()<<\"创建表失败\"<<query.lastError(); return -1; } else { qDebug()<<\"创建表成功!\"; } // 插入数据 if(!query.exec(\"INSERT INTO students(id,name,age) VALUES (1,\'张三\',18),(2,\'李四\',20),(3,\'王五\',50);\")) { qDebug()<<\"插入数据失败:\"<<query.lastError(); return -1; } else { qDebug()<<\"插入数据成功!\"; } // 打印所有数据信息 if(!query.exec(\"SELECT * FROM students\")) { qDebug()<<\"打印数据信息失败!\"<<query.lastError();; return -1; } else { // 获取字段数量 auto filedCount = query.record().count(); while(query.next()) { // 遍历所有字段 for(size_t i = 0;i<filedCount;++i) { qDebug()<<query.value(i).toString(); } } } db.close();

实战练习

完成一个简易的学生管理系统,主要功能包括数据库的连接和断开,以及学生数据信息增删改查。

界面设计

界面布局

Qt从入门到入土(十一) -数据库操作--MySQL_qt mysql

qss界面样式

时间有限,仅对QPushButton进行美化

QPushButton{height:40px;border-radius:10px;background-color:rgb(27,244,255);font-size:14px;}QPushButton:hover{background-color:rgb(23,212,222);}

功能实现

增加数据

Qt从入门到入土(十一) -数据库操作--MySQL_qt mysql

Qt从入门到入土(十一) -数据库操作--MySQL_qt mysql 

void Widget::addData(){ if(ui->id_edit->text().isEmpty() || ui->name_edit->text().isEmpty() || ui->age_edit->text().isEmpty() || ui->sex_edit->text().isEmpty()) { ui->showInfo->clear(); ui->showInfo->append(\"增加数据失败!请先输入信息!\"); return; } ui->showInfo->clear(); // trimmed函数的作用是去除首尾空格 int num = ui->id_edit->text().trimmed().toInt(); QString name = ui->name_edit->text().trimmed(); int age = ui->age_edit->text().trimmed().toInt(); QString sex = ui->sex_edit->text().trimmed(); // 检查是否存在匹配的学生数据 if (!query->prepare(\"SELECT * FROM students WHERE num = :num\")) { ui->showInfo->append(\"查询学生数据的准备注入语句失败!\"); qDebug()<lastError().text(); return; } query->bindValue(\":num\", num); if (!query->exec()) { ui->showInfo->append(\"查询学生数据失败!\"); qDebug()<lastError().text(); return; } if (query->next()) { ui->showInfo->append(\"增加数据失败!该学生已存在!\"); return; } // 执行增加学生数据信息的操作 if(!query->prepare(QString(\"INSERT INTO students(num,name,age,sex) VALUES(\'%1\',\'%2\',\'%3\',\'%4\')\").arg(num).arg(name).arg(age).arg(sex))) { ui->showInfo->append(\"增加学生数据的准备注入语句失败!\"); qDebug()<exec()) { ui->showInfo->append(\"增加学生数据失败!\"); qDebug()<showInfo->append(\"增加数据成功!\"); ui->showInfo->append(\"插入数据数量:\"+QString::number(query->size())); ui->showInfo->append((\"插入数据信息:\")); ui->showInfo->append(QString(\"学号:%1\").arg(num)); ui->showInfo->append(QString(\"姓名:%1\").arg(name)); ui->showInfo->append(QString(\"年龄:%1\").arg(age)); ui->showInfo->append(QString(\"性别:%1\").arg(sex));}

删除数据

根据学号查询到指定数据并删除,若未找到该学生信息则删除数据失败

Qt从入门到入土(十一) -数据库操作--MySQL_qt mysql

Qt从入门到入土(十一) -数据库操作--MySQL_qt mysql 

void Widget::delData(){ if(ui->id_edit->text().isEmpty()) { ui->showInfo->clear(); ui->showInfo->append(\"删除数据失败!请先输入需要删除的学生的学号!\"); return; } ui->showInfo->clear(); int num = ui->id_edit->text().trimmed().toInt(); // 检查是否存在匹配的学生数据 if (!query->prepare(\"SELECT * FROM students WHERE num = :num\")) { ui->showInfo->append(\"查询学生数据的准备注入语句失败!\"); qDebug()<lastError().text(); return; } query->bindValue(\":num\", num); if (!query->exec()) { ui->showInfo->append(\"查询学生数据失败!\"); qDebug()<lastError().text(); return; } if (!query->next()) { ui->showInfo->append(\"删除数据失败!未找到该学生!\"); return; } // 执行删除学生信息操作 if(!query->prepare(QString(\"DELETE FROM students WHERE num=%1\").arg(num))) { ui->showInfo->append(\"删除学生数据的准备注入语句失败!\"); qDebug()<exec()) { ui->showInfo->append(\"删除学生数据失败!\"); qDebug()<showInfo->append(\"删除数据成功!\");}

修改数据

根据学号查询到指定数据并修改,若未找到该学生信息则修改数据失败

Qt从入门到入土(十一) -数据库操作--MySQL_qt mysql

Qt从入门到入土(十一) -数据库操作--MySQL_qt mysql

 

void Widget::modData(){ if(ui->id_edit->text().isEmpty() || ui->name_edit->text().isEmpty() || ui->age_edit->text().isEmpty() || ui->sex_edit->text().isEmpty()) { ui->showInfo->clear(); ui->showInfo->append(\"修改数据失败!请先输入新的学生信息!学生学号不能改变!\"); return; } ui->showInfo->clear(); // trimmed函数的作用是去除首尾空格 int num = ui->id_edit->text().trimmed().toInt(); QString name = ui->name_edit->text().trimmed(); int age = ui->age_edit->text().trimmed().toInt(); QString sex = ui->sex_edit->text().trimmed(); // 检查是否存在匹配的学生数据 if (!query->prepare(\"SELECT * FROM students WHERE num = :num\")) { ui->showInfo->append(\"查询学生数据的准备注入语句失败!\"); qDebug()<lastError().text(); return; } query->bindValue(\":num\", num); if (!query->exec()) { ui->showInfo->append(\"查询学生数据失败!\"); qDebug()<lastError().text(); return; } if (!query->next()) { ui->showInfo->append(\"修改数据失败!未找到该学生!\"); return; } // 执行更新操作 if(!query->prepare(QString(\"UPDATE students SET name = :name , age = :age , sex = :sex WHERE num = :num\") .arg(name).arg(age).arg(sex).arg(num))) { ui->showInfo->append(\"修改学生数据的准备注入语句失败!\"); qDebug()<bindValue(\":name\", name); query->bindValue(\":age\", age); query->bindValue(\":sex\", sex); query->bindValue(\":num\", num); if(!query->exec()) { ui->showInfo->append(\"修改学生数据失败!\"); qDebug()<showInfo->append(\"修改数据成功!\"); ui->showInfo->append((\"修改后的数据信息为:\")); ui->showInfo->append(QString(\"学号:%1\").arg(num)); ui->showInfo->append(QString(\"姓名:%1\").arg(name)); ui->showInfo->append(QString(\"年龄:%1\").arg(age)); ui->showInfo->append(QString(\"性别:%1\").arg(sex));}

查询数据

根据学号查询

Qt从入门到入土(十一) -数据库操作--MySQL_qt mysql

 Qt从入门到入土(十一) -数据库操作--MySQL_qt mysql

void Widget::serData(){ if(ui->id_edit->text().isEmpty()) { ui->showInfo->clear(); ui->showInfo->append(\"查询数据失败!请先输入需要查询的学生的学号!\"); return; } ui->showInfo->clear(); int num = ui->id_edit->text().trimmed().toInt(); if(!query->prepare(QString(\"SELECT * FROM students WHERE num=%1\").arg(num))) { ui->showInfo->append(\"查询学生数据的准备注入语句失败!\"); qDebug()<exec()) { ui->showInfo->append(\"查询数据失败!未找到该学生!\"); qDebug()<next() 遍历查询结果 if(query->next()) { QSqlRecord rec = query->record(); ui->showInfo->append(\"查询数据成功!\"); ui->showInfo->append(\"查询数据结果为:\"); ui->showInfo->append(QString(\"学号:\")+QString::number(rec.value(\"num\").toInt())); ui->showInfo->append(QString(\"姓名:\")+rec.value(\"name\").toString()); ui->showInfo->append(QString(\"年龄:\")+QString::number(rec.value(\"age\").toInt())); ui->showInfo->append(QString(\"性别:\")+rec.value(\"sex\").toString()); } else { ui->showInfo->append(\"查询数据失败!未找到该学生!\"); }}

连接数据库

void Widget::connectDatabase(){ database = QSqlDatabase::addDatabase(\"QMYSQL\"); database.setHostName(\"localhost\"); // 设置主机名 database.setDatabaseName(\"studentManagerSystem\"); database.setPort(3306); // 设置端口号 database.setUserName(\"root\"); database.setPassword(\"12345678\"); if(!database.open()) { ui->showInfo->append(QString(\"MySQL数据库打开失败!\\n\")+database.lastError().text()); return; } ui->showInfo->clear(); ui->showInfo->append(\"MySQL数据库连接成功!\"); // 连接数据库后可以输入信息 ui->id_edit->setReadOnly(false); ui->name_edit->setReadOnly(false); ui->age_edit->setReadOnly(false); ui->sex_edit->setReadOnly(false); query = new QSqlQuery(database);}

断开数据库

void Widget::disconnectDatabase(){ if(database.isOpen()) { database.close(); ui->showInfo->clear(); ui->showInfo->append(\"MySQL数据库成功断开!\"); // 禁止输入信息 ui->id_edit->setReadOnly(true); ui->name_edit->setReadOnly(true); ui->age_edit->setReadOnly(true); ui->sex_edit->setReadOnly(true); } else { ui->showInfo->clear(); ui->showInfo->append(\"MySQL数据库暂未连接!\"); }}

综合代码

main.cpp

#include \"widget.h\"#include #include #include #include #include int main(int argc, char *argv[]){ QApplication a(argc, argv); Widget w; w.show(); return a.exec();}

widget.h

#ifndef WIDGET_H#define WIDGET_H#include #include #include #include #include QT_BEGIN_NAMESPACEnamespace Ui {class Widget;}QT_END_NAMESPACEclass Widget : public QWidget{ Q_OBJECTpublic: Widget(QWidget *parent = nullptr); ~Widget();private: void initUI(); void connectDatabase(); // 连接数据库 void disconnectDatabase(); // 断开数据库 void addData(); // 增加数据 void delData(); // 删除数据 void serData(); // 查询数据 void modData(); // 修改数据 void showDriver(); // 显示驱动信息private: Ui::Widget *ui; QSqlDatabase database; QSqlQuery* query; QSqlError error; QSqlRecord record;};#endif // WIDGET_H

widget.cpp

#include \"widget.h\"#include \"./ui_widget.h\"#include #include Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget){ ui->setupUi(this); this->setWindowTitle(\"学生管理系统\"); // 未连接数据库不能输入信息 ui->id_edit->setReadOnly(true); ui->name_edit->setReadOnly(true); ui->age_edit->setReadOnly(true); ui->sex_edit->setReadOnly(true); QFile file(\":/Resources/style.css\"); if(file.open(QIODevice::ReadOnly)) { this->setStyleSheet(file.readAll()); } initUI();}Widget::~Widget(){ delete ui;}void Widget::initUI(){ showDriver(); // 连接数据库 connect(ui->connect_btn,&QPushButton::clicked,this,&Widget::connectDatabase); // 断开数据库连接 connect(ui->disconnect_btn,&QPushButton::clicked,this,&Widget::disconnectDatabase); // 增加数据 connect(ui->add_btn,&QPushButton::clicked,this,&Widget::addData); // 删除数据 connect(ui->del_btn,&QPushButton::clicked,this,&Widget::delData); // 修改数据 connect(ui->modify_btn,&QPushButton::clicked,this,&Widget::modData); // 查询数据 connect(ui->search_btn,&QPushButton::clicked,this,&Widget::serData);}void Widget::connectDatabase(){ database = QSqlDatabase::addDatabase(\"QMYSQL\"); database.setHostName(\"localhost\"); // 设置主机名 database.setDatabaseName(\"studentManagerSystem\"); database.setPort(3306); // 设置端口号 database.setUserName(\"root\"); database.setPassword(\"12345678\"); if(!database.open()) { ui->showInfo->append(QString(\"MySQL数据库打开失败!\\n\")+database.lastError().text()); return; } ui->showInfo->clear(); ui->showInfo->append(\"MySQL数据库连接成功!\"); // 连接数据库后可以输入信息 ui->id_edit->setReadOnly(false); ui->name_edit->setReadOnly(false); ui->age_edit->setReadOnly(false); ui->sex_edit->setReadOnly(false); query = new QSqlQuery(database);}void Widget::disconnectDatabase(){ if(database.isOpen()) { database.close(); ui->showInfo->clear(); ui->showInfo->append(\"MySQL数据库成功断开!\"); // 禁止输入信息 ui->id_edit->setReadOnly(true); ui->name_edit->setReadOnly(true); ui->age_edit->setReadOnly(true); ui->sex_edit->setReadOnly(true); } else { ui->showInfo->clear(); ui->showInfo->append(\"MySQL数据库暂未连接!\"); }}void Widget::addData(){ if(ui->id_edit->text().isEmpty() || ui->name_edit->text().isEmpty() || ui->age_edit->text().isEmpty() || ui->sex_edit->text().isEmpty()) { ui->showInfo->clear(); ui->showInfo->append(\"增加数据失败!请先输入信息!\"); return; } ui->showInfo->clear(); // trimmed函数的作用是去除首尾空格 int num = ui->id_edit->text().trimmed().toInt(); QString name = ui->name_edit->text().trimmed(); int age = ui->age_edit->text().trimmed().toInt(); QString sex = ui->sex_edit->text().trimmed(); // 检查是否存在匹配的学生数据 if (!query->prepare(\"SELECT * FROM students WHERE num = :num\")) { ui->showInfo->append(\"查询学生数据的准备注入语句失败!\"); qDebug()<lastError().text(); return; } query->bindValue(\":num\", num); if (!query->exec()) { ui->showInfo->append(\"查询学生数据失败!\"); qDebug()<lastError().text(); return; } if (query->next()) { ui->showInfo->append(\"增加数据失败!该学生已存在!\"); return; } // 执行增加学生数据信息的操作 if(!query->prepare(QString(\"INSERT INTO students(num,name,age,sex) VALUES(\'%1\',\'%2\',\'%3\',\'%4\')\").arg(num).arg(name).arg(age).arg(sex))) { ui->showInfo->append(\"增加学生数据的准备注入语句失败!\"); qDebug()<exec()) { ui->showInfo->append(\"增加学生数据失败!\"); qDebug()<showInfo->append(\"增加数据成功!\"); ui->showInfo->append(\"插入数据数量:\"+QString::number(query->size())); ui->showInfo->append((\"插入数据信息:\")); ui->showInfo->append(QString(\"学号:%1\").arg(num)); ui->showInfo->append(QString(\"姓名:%1\").arg(name)); ui->showInfo->append(QString(\"年龄:%1\").arg(age)); ui->showInfo->append(QString(\"性别:%1\").arg(sex));}void Widget::delData(){ if(ui->id_edit->text().isEmpty()) { ui->showInfo->clear(); ui->showInfo->append(\"删除数据失败!请先输入需要删除的学生的学号!\"); return; } ui->showInfo->clear(); int num = ui->id_edit->text().trimmed().toInt(); // 检查是否存在匹配的学生数据 if (!query->prepare(\"SELECT * FROM students WHERE num = :num\")) { ui->showInfo->append(\"查询学生数据的准备注入语句失败!\"); qDebug()<lastError().text(); return; } query->bindValue(\":num\", num); if (!query->exec()) { ui->showInfo->append(\"查询学生数据失败!\"); qDebug()<lastError().text(); return; } if (!query->next()) { ui->showInfo->append(\"删除数据失败!未找到该学生!\"); return; } // 执行删除学生信息操作 if(!query->prepare(QString(\"DELETE FROM students WHERE num=%1\").arg(num))) { ui->showInfo->append(\"删除学生数据的准备注入语句失败!\"); qDebug()<exec()) { ui->showInfo->append(\"删除学生数据失败!\"); qDebug()<showInfo->append(\"删除数据成功!\");}void Widget::serData(){ if(ui->id_edit->text().isEmpty()) { ui->showInfo->clear(); ui->showInfo->append(\"查询数据失败!请先输入需要查询的学生的学号!\"); return; } ui->showInfo->clear(); int num = ui->id_edit->text().trimmed().toInt(); if(!query->prepare(QString(\"SELECT * FROM students WHERE num=%1\").arg(num))) { ui->showInfo->append(\"查询学生数据的准备注入语句失败!\"); qDebug()<exec()) { ui->showInfo->append(\"查询数据失败!未找到该学生!\"); qDebug()<next() 遍历查询结果 if(query->next()) { QSqlRecord rec = query->record(); ui->showInfo->append(\"查询数据成功!\"); ui->showInfo->append(\"查询数据结果为:\"); ui->showInfo->append(QString(\"学号:\")+QString::number(rec.value(\"num\").toInt())); ui->showInfo->append(QString(\"姓名:\")+rec.value(\"name\").toString()); ui->showInfo->append(QString(\"年龄:\")+QString::number(rec.value(\"age\").toInt())); ui->showInfo->append(QString(\"性别:\")+rec.value(\"sex\").toString()); } else { ui->showInfo->append(\"查询数据失败!未找到该学生!\"); }}void Widget::modData(){ if(ui->id_edit->text().isEmpty() || ui->name_edit->text().isEmpty() || ui->age_edit->text().isEmpty() || ui->sex_edit->text().isEmpty()) { ui->showInfo->clear(); ui->showInfo->append(\"修改数据失败!请先输入新的学生信息!学生学号不能改变!\"); return; } ui->showInfo->clear(); // trimmed函数的作用是去除首尾空格 int num = ui->id_edit->text().trimmed().toInt(); QString name = ui->name_edit->text().trimmed(); int age = ui->age_edit->text().trimmed().toInt(); QString sex = ui->sex_edit->text().trimmed(); // 检查是否存在匹配的学生数据 if (!query->prepare(\"SELECT * FROM students WHERE num = :num\")) { ui->showInfo->append(\"查询学生数据的准备注入语句失败!\"); qDebug()<lastError().text(); return; } query->bindValue(\":num\", num); if (!query->exec()) { ui->showInfo->append(\"查询学生数据失败!\"); qDebug()<lastError().text(); return; } if (!query->next()) { ui->showInfo->append(\"修改数据失败!未找到该学生!\"); return; } // 执行更新操作 if(!query->prepare(QString(\"UPDATE students SET name = :name , age = :age , sex = :sex WHERE num = :num\") .arg(name).arg(age).arg(sex).arg(num))) { ui->showInfo->append(\"修改学生数据的准备注入语句失败!\"); qDebug()<bindValue(\":name\", name); query->bindValue(\":age\", age); query->bindValue(\":sex\", sex); query->bindValue(\":num\", num); if(!query->exec()) { ui->showInfo->append(\"修改学生数据失败!\"); qDebug()<showInfo->append(\"修改数据成功!\"); ui->showInfo->append((\"修改后的数据信息为:\")); ui->showInfo->append(QString(\"学号:%1\").arg(num)); ui->showInfo->append(QString(\"姓名:%1\").arg(name)); ui->showInfo->append(QString(\"年龄:%1\").arg(age)); ui->showInfo->append(QString(\"性别:%1\").arg(sex));}void Widget::showDriver(){ auto list = database.drivers(); // 显示驱动信息 ui->showInfo->append(\"当前Qt支持的驱动有:\"); for(size_t i = 0;ishowInfo->append(list[i]); }}