在这个案例中,一方面实践了QSqlDatabase类和QSqlQuery类的基本用法,另一方面也验证了在Qt程序中访问MySQL数据库的可行性。
Qt和MySQL是来自不技术社区和企业的软件产品。二者在版本上很难保持协调一致。因此从Qt5以后,Qt官方不再提供预构建的MySQL驱动。需要MySQL驱动的用户可以利用Qt官方提供的驱动源码,结合其系统上实际安装的MySQL,自行构建MySQL驱动,以实现驱动与数据库的完美匹配。
编辑C:\Qt\Qt5.12.8\5.12.8\Src\qtbase\src\plugins\sqldrivers目录下的qsqldriverbase.pri文件,注释第4行,添加第5行:
xxxxxxxxxx
101QT = core core-private sql-private
2
3# For QMAKE_USE in the parent projects.
4# include($$shadowed($$PWD)/qtsqldrivers-config.pri)
5include(./configure.pri)
6
7PLUGIN_TYPE = sqldrivers
8load(qt_plugin)
9
10DEFINES += QT_NO_CAST_TO_ASCII QT_NO_CAST_FROM_ASCII
编辑C:\Qt\Qt5.12.8\5.12.8\Src\qtbase\src\plugins\sqldrivers\mysql目录下的mysql.pro文件,注释第6行,添加第13、14、15行:
xxxxxxxxxx
151TARGET = qsqlmysql
2
3HEADERS += $$PWD/qsql_mysql_p.h
4SOURCES += $$PWD/qsql_mysql.cpp $$PWD/main.cpp
5
6# QMAKE_USE += mysql
7
8OTHER_FILES += mysql.json
9
10PLUGIN_CLASS_NAME = QMYSQLDriverPlugin
11include(../qsqldriverbase.pri)
12
13INCLUDEPATH += "C:\Program Files\MySQL\MySQL Server 8.0\include"
14LIBS += "C:\Program Files\MySQL\MySQL Server 8.0\lib\libmysql.lib"
15DESTDIR = "C:\Qt\Qt5.12.8\5.12.8\mingw73_64\plugins\sqldrivers"
用QtCreator打开C:\Qt\Qt5.12.8\5.12.8\Src\qtbase\src\plugins\sqldrivers\mysql目录下的mysql.pro文件,构建Release和Debug版本。在C:\Qt\Qt5.12.8\5.12.8\mingw73_64\plugins\sqldrivers目录下可以看到下面这两个动态链接库文件:
qsqlmysql.dll:Release版本的MySQL驱动
qsqlmysqld.dll:Debug版本的MySQL驱动
将C:\Program Files\MySQL\MySQL Server 8.0\lib目录下的libmysql.dll文件,拷贝到C:\Qt\Qt5.12.8\5.12.8\mingw73_64\bin目录下。
通过QtCreator,在C:\Users\Minwei\Projects\Qt路径下,创建名为DBTest的控制台(Console)项目,并在项目文件中添加第2行:
xxxxxxxxxx
241QT -= gui
2QT += sql
3
4CONFIG += c++11 console
5CONFIG -= app_bundle
6
7# The following define makes your compiler emit warnings if you use
8# any Qt feature that has been marked deprecated (the exact warnings
9# depend on your compiler). Please consult the documentation of the
10# deprecated API in order to know how to port your code away from it.
11DEFINES += QT_DEPRECATED_WARNINGS
12
13# You can also make your code fail to compile if it uses deprecated APIs.
14# In order to do so, uncomment the following line.
15# You can also select to disable deprecated APIs only up to a certain version of Qt.
16#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
17
18SOURCES += \
19main.cpp
20
21# Default rules for deployment.
22qnx: target.path = /tmp/$${TARGET}/bin
23else: unix:!android: target.path = /opt/$${TARGET}/bin
24!isEmpty(target.path): INSTALLS += target
C:\Users\Minwei\Projects\Qt\DBTest\qt_testdb.sql:
xxxxxxxxxx
311DROP DATABASE IF EXISTS qt_testdb;
2CREATE DATABASE qt_testdb;
3USE qt_testdb;
4
5SET NAMES utf8mb4;
6
7CREATE TABLE `t_department` (
8 `id` int UNSIGNED NOT NULL AUTO_INCREMENT,
9 `name` varchar(64) DEFAULT NULL,
10 PRIMARY KEY (`id`)
11) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
12
13INSERT INTO `t_department` VALUES (1, '研发部');
14INSERT INTO `t_department` VALUES (2, '市场部');
15INSERT INTO `t_department` VALUES (3, '人力资源部');
16
17CREATE TABLE `t_employee` (
18 `id` int UNSIGNED NOT NULL AUTO_INCREMENT,
19 `name` varchar(32) DEFAULT NULL,
20 `gender` varchar(16) DEFAULT NULL,
21 `department_id` int UNSIGNED DEFAULT NULL,
22 `salary` decimal(8,2) DEFAULT NULL,
23 PRIMARY KEY (`id`),
24 CONSTRAINT `employee_of_department` FOREIGN KEY (`department_id`) REFERENCES `t_department` (`id`)
25) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
26
27INSERT INTO `t_employee` VALUES (1, '张飞', '男', 1, 20000);
28INSERT INTO `t_employee` VALUES (2, '赵云', '男', 1, 30000);
29INSERT INTO `t_employee` VALUES (3, '关羽', '男', 2, 15000);
30INSERT INTO `t_employee` VALUES (4, '黄忠', '男', 2, 25000);
31INSERT INTO `t_employee` VALUES (5, '马超', '男', 3, 20000);
在C:\Users\Minwei\Projects\Qt\DBTest目录下启动控制台,并执行如下命令:
xxxxxxxxxx
41C:\Users\Minwei\Projects\Qt\DBTest> mysql -uroot -p123456
2mysql> source qt_testdb.sql
3...
4mysql> exit
C:\Users\Minwei\Projects\Qt\DBTest\main.cpp:
xxxxxxxxxx
511
2
3
4
5
6
7int main(int argc, char *argv[])
8{
9 QCoreApplication a(argc, argv);
10
11 QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
12 db.setHostName("localhost");
13 db.setPort(3306);
14 db.setUserName("root");
15 db.setPassword("123456");
16 db.setDatabaseName("qt_testdb");
17 if (!db.open())
18 {
19 qDebug() << "连接数据库失败:" << db.lastError().text();
20 return -1;
21 }
22
23 qDebug() << "连接数据库成功!";
24
25 qDebug() << "----------------------------------------------";
26
27 QSqlQuery query;
28
29 query.exec("select * from t_department");
30 while (query.next())
31 {
32 qDebug()
33 << query.value(0).toInt() << '\t'
34 << query.value(1).toString();
35 }
36
37 qDebug() << "----------------------------------------------";
38
39 query.exec("select * from t_employee");
40 while (query.next())
41 {
42 qDebug()
43 << query.value(0).toInt() << '\t'
44 << query.value(1).toString() << '\t'
45 << query.value(2).toString() << '\t'
46 << query.value(3).toInt() << '\t'
47 << query.value(4).toDouble();
48 }
49
50 return a.exec();
51}
运行效果如图所示: