引言
在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();
实战练习
完成一个简易的学生管理系统,主要功能包括数据库的连接和断开,以及学生数据信息增删改查。
界面设计
界面布局

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);
}
功能实现
增加数据


cpp
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()<<query->lastError().text();
return;
}
query->bindValue(":num", num);
if (!query->exec())
{
ui->showInfo->append("查询学生数据失败!");
qDebug()<<query->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()<<database.lastError().text();
return;
}
if(!query->exec())
{
ui->showInfo->append("增加学生数据失败!");
qDebug()<<database.lastError().text();
return;
}
ui->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));
}
删除数据
根据学号查询到指定数据并删除,若未找到该学生信息则删除数据失败


cpp
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()<<query->lastError().text();
return;
}
query->bindValue(":num", num);
if (!query->exec())
{
ui->showInfo->append("查询学生数据失败!");
qDebug()<<query->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()<<database.lastError().text();
return;
}
if(!query->exec())
{
ui->showInfo->append("删除学生数据失败!");
qDebug()<<database.lastError().text();
return;
}
ui->showInfo->append("删除数据成功!");
}
修改数据
根据学号查询到指定数据并修改,若未找到该学生信息则修改数据失败


cpp
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()<<query->lastError().text();
return;
}
query->bindValue(":num", num);
if (!query->exec())
{
ui->showInfo->append("查询学生数据失败!");
qDebug()<<query->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()<<database.lastError().text();
return;
}
query->bindValue(":name", name);
query->bindValue(":age", age);
query->bindValue(":sex", sex);
query->bindValue(":num", num);
if(!query->exec())
{
ui->showInfo->append("修改学生数据失败!");
qDebug()<<database.lastError().text();
return;
}
ui->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));
}
查询数据
根据学号查询


cpp
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()<<database.lastError().text();
return;
}
if(!query->exec())
{
ui->showInfo->append("查询数据失败!未找到该学生!");
qDebug()<<database.lastError().text();
return;
}
// 使用 query->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("查询数据失败!未找到该学生!");
}
}
连接数据库
cpp
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);
}
断开数据库
cpp
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
cpp
#include "widget.h"
#include <QSqlDatabase>
#include <QApplication>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlRecord>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.h
cpp
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QSqlRecord>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
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
cpp
#include "widget.h"
#include "./ui_widget.h"
#include <QFile>
#include <QStringList>
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()<<query->lastError().text();
return;
}
query->bindValue(":num", num);
if (!query->exec())
{
ui->showInfo->append("查询学生数据失败!");
qDebug()<<query->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()<<database.lastError().text();
return;
}
if(!query->exec())
{
ui->showInfo->append("增加学生数据失败!");
qDebug()<<database.lastError().text();
return;
}
ui->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()<<query->lastError().text();
return;
}
query->bindValue(":num", num);
if (!query->exec())
{
ui->showInfo->append("查询学生数据失败!");
qDebug()<<query->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()<<database.lastError().text();
return;
}
if(!query->exec())
{
ui->showInfo->append("删除学生数据失败!");
qDebug()<<database.lastError().text();
return;
}
ui->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()<<database.lastError().text();
return;
}
if(!query->exec())
{
ui->showInfo->append("查询数据失败!未找到该学生!");
qDebug()<<database.lastError().text();
return;
}
// 使用 query->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()<<query->lastError().text();
return;
}
query->bindValue(":num", num);
if (!query->exec())
{
ui->showInfo->append("查询学生数据失败!");
qDebug()<<query->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()<<database.lastError().text();
return;
}
query->bindValue(":name", name);
query->bindValue(":age", age);
query->bindValue(":sex", sex);
query->bindValue(":num", num);
if(!query->exec())
{
ui->showInfo->append("修改学生数据失败!");
qDebug()<<database.lastError().text();
return;
}
ui->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;i<list.length();++i)
{
ui->showInfo->append(list[i]);
}
}