最近在Windows平台下用QT5.14.2开发一个需要连接MySQL8.0的项目时,遇到了驱动不兼容的经典难题。官方预编译的驱动在MingGW环境下要么缺失要么版本不匹配,这让我不得不走上源码编译驱动的道路。本文将完整记录这个过程中的技术细节和解决方案,希望能帮助遇到同样困境的开发者少走弯路。
在开始之前,我们需要确保基础环境配置正确。我的开发环境是Windows10专业版,安装了QT5.14.2和MingGW64-bit编译器,数据库使用的是mysql-8.0.23-winx64。
常见问题排查清单:
plugins/sqldrivers文件夹,确认是否已有qsqlmysql.dll文件libmysql.dll是否已复制到QT的bin目录提示:QT官方提供的预编译驱动往往只包含最常用的配置组合,对于较新的MySQL版本或特定编译器环境,手动编译驱动几乎是必经之路。
首先需要定位到QT源码中的MySQL驱动项目。完整路径通常是:
code复制Qt5.14.2\5.14.2\Src\qtbase\src\plugins\sqldrivers\mysql
这个目录下的mysql.pro文件是我们需要修改的核心配置文件。
打开mysql.pro文件后,需要进行以下几处关键修改:
qmake复制TARGET = qsqlmysql
HEADERS += $$PWD/qsql_mysql_p.h
SOURCES += $$PWD/qsql_mysql.cpp $$PWD/main.cpp
# 必须注释掉这一行
# QMAKE_USE += mysql
OTHER_FILES += mysql.json
PLUGIN_CLASS_NAME = QMYSQLDriverPlugin
# 根据实际路径修改以下三项
LIBS += -L $$quote(D:/mysql-8.0.23-winx64/lib) -llibmysql
INCLUDEPATH += $$quote(D:/mysql-8.0.23-winx64/include)
DEPENDPATH += $$quote(D:/mysql-8.0.23-winx64/include)
include(../qsqldriverbase.pri)
路径配置注意事项:
| 配置项 | 说明 | 示例值 |
|---|---|---|
| LIBS | MySQL库文件路径 | -L $$quote(D:/mysql/lib) -llibmysql |
| INCLUDEPATH | MySQL头文件路径 | $$quote(D:/mysql/include) |
| DEPENDPATH | 依赖文件路径 | 通常与INCLUDEPATH相同 |
完成配置后,在QT Creator中打开mysql.pro项目,直接构建即可。常见的编译错误包括:
编译成功后,会在构建目录生成qsqlmysql.dll和调试版本的qsqlmysql.dll.debug文件。
将生成的驱动文件复制到QT的插件目录:
code复制Qt5.14.2\5.14.2\mingw73_64\plugins\sqldrivers
同时确保MySQL的libmysql.dll文件已经存在于:
code复制Qt5.14.2\5.14.2\mingw73_64\bin
下面是一个完整的连接测试示例:
cpp复制#include <QCoreApplication>
#include <QtSql>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setPort(3306);
db.setDatabaseName("test_db");
db.setUserName("root");
db.setPassword("yourpassword");
if (!db.open()) {
qDebug() << "Failed to connect:" << db.lastError().text();
return -1;
}
qDebug() << "Connected successfully!";
// 执行简单查询
QSqlQuery query;
if (query.exec("SELECT VERSION()")) {
while (query.next()) {
qDebug() << "MySQL Server version:" << query.value(0).toString();
}
}
db.close();
return a.exec();
}
连接参数详解:
QMYSQL:指定使用MySQL驱动setHostName():数据库服务器地址,本地为localhostsetPort():MySQL默认端口3306setDatabaseName():要连接的具体数据库名setUserName()和setPassword():数据库认证信息对于需要频繁建立数据库连接的应用,建议使用连接池:
cpp复制QSqlDatabase::addDatabase("QMYSQL", "connection1");
QSqlDatabase::addDatabase("QMYSQL", "connection2");
// 使用时通过connectionName获取特定连接
确保QT与MySQL之间的编码一致,避免中文乱码:
cpp复制db.exec("SET NAMES 'utf8mb4'");
当连接出现问题时,可以通过以下方式获取详细错误信息:
cpp复制if (!db.open()) {
QSqlError error = db.lastError();
qDebug() << "Error type:" << error.type();
qDebug() << "Error number:" << error.number();
qDebug() << "Error text:" << error.text();
qDebug() << "Driver text:" << error.driverText();
qDebug() << "Database text:" << error.databaseText();
}
虽然本文以Windows平台为例,但在其他操作系统上编译MySQL驱动的过程也大同小异:
Linux/macOS关键差异:
/usr/lib/mysql或/usr/local/mysql/liblibmysqlclient-devlibmysqlclient.so或libmysqlclient.dylib在实际项目中,我发现MySQL8.0默认的身份验证插件caching_sha2_password可能会导致连接问题。解决方法是在MySQL中创建用户时指定传统验证方式:
sql复制CREATE USER 'qtuser'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
另一个实用技巧是,在开发过程中可以启用QT的SQL调试输出,帮助诊断问题:
cpp复制QLoggingCategory::setFilterRules("qt.sql=true");
这些经验都是经过多次尝试和失败后总结出来的,希望能帮助开发者们更顺利地完成QT与MySQL8.0的集成工作。