
简介在Linux平台下使用Qt连接MySQL数据库是许多C/Qt开发者的常见需求这份文档正是一份围绕该场景整理的实操说明适合需要在Ubuntu等Linux环境中完成数据库驱动配置与项目联调的开发人员。资源包内共1个doc文档压缩包大小142KB从安装libmysqlclient-dev客户端库开始详细讲解了在Qt源码目录下编译MySQL驱动、生成并拷贝libqsqlmysql.so文件的完整流程同时给出在.pro文件中添加QT sql、LIBS与INCLUDEPATH的配置方法并附上基于QtSql的数据库连接和SELECT查询代码示例可帮助读者理清编译路径、依赖库和权限处理等常见问题。已有635人学习对于正在使用Qt Creator进行Linux端数据库开发的初学者或中级工程师具有不错的参考价值。1. Linux 下 QT 连接 MySQL第一道坎是 QMYSQL 驱动没编译在 Linux 上把 QT 和 MySQL 分别装好写第一段连接代码时多数人遇见的不是 SQL 语法错误而是运行时一句QSqlDatabase: QMYSQL driver not loaded。原因是 QT 官方离线安装包和大部分发行版仓库里的 QT 都不自带 MySQL 驱动程序在驱动层就断了跟服务端配置无关。下面按依赖安装、驱动编译、连接代码、收尾验证四个部分把这条链路走完先装对 MySQL 客户端开发库再从 QT 源码编译 QMYSQL 驱动接着用 QSqlDatabase 写出最小可运行代码最后给一个驱动自检脚本和 utf8mb4 中文编码的收尾。适合用 Qt Widgets 或 QML 写桌面应用、不想引入 ODBC 中间层的开发者也适合在 CI 机器上做部署前验证。2. 安装 MySQL 客户端库并核对 QT 的 sqldrivers 目录正式编译驱动之前先保证底层依赖齐全。很多教程直接跳到 qmake 那一步结果 make 阶段报出一堆mysql.h: No such file or directory回头再补装客户端库反而浪费时间。这一章把 MySQL 服务端、客户端开发库、QT 插件目录三件事一次核对完后两步是 Linux 下 QT 连接 MySQL 最常见的遗漏点。2.1 安装 MySQL 服务端apt 与 dnf 两条命令Debian / Ubuntu 的安装命令sudo apt update sudo apt install mysql-server -y sudo systemctl enable --now mysql systemctl status mysql --no-pagerCentOS / RHEL 系用 dnfAppStream 源里直接有 mysql-serversudo dnf install mysql-server -y sudo systemctl enable --now mysqld systemctl status mysqld --no-pager装完先用mysql --version确认版本。MySQL 8.0 在 Ubuntu 上安装后 root 默认走 auth_socket 认证sudo mysql能直接进5.7 初始化时会往/var/log/mysqld.log写临时密码首次登录后必须改掉。服务端跑起来之后顺手确认端口在监听ss -lntp | grep 3306。端口没起来后面 QT 程序报的错会是Cant connect to MySQL server (111)和驱动无关先排除服务端。2.2 libmysqlclient-dev 是编译驱动的刚需编译 QMYSQL 驱动需要两样东西mysql.h头文件和libmysqlclient客户端库。只装服务端不够驱动源码里#include mysql.h链接阶段还要-lmysqlclient缺任何一个都会被拦在编译期。sudo apt install libmysqlclient-dev -y mysql_config --version mysql_config --libsmysql_config --libs的输出一般是-L/usr/lib/x86_64-linux-gnu -lmysqlclient这个路径在下一章编译命令里直接用。CentOS 系对应的包名是mysql-devel装完用mysql_config --version验证。这里有个隐蔽的坑如果系统里残留 MariaDB 的开发库mysql_config可能指向 MariaDB 的兼容实现通常也能编过但生产环境建议卸载干净再装 MySQL 官方客户端库头文件混合版本会导致链接期出现undefined reference最难排查。2.3 核对 QT 安装方式与 plugins/sqldrivers 现状QT 的两个常见安装来源决定驱动拿到的路径完全不同QT 来源驱动获取方式适用场景官方离线安装包5.14.2 等从源码编译 libqsqlmysql.so固定版本、跨发行版分发发行版 apt / dnf 安装安装 libqt5sql5-mysql开发测试不关心 QT 小版本系统仓库里的 QT 可以直接装现成驱动包sudo apt install libqt5sql5-mysql -y这个包会把libqsqlmysql.so放进系统 QT 的插件目录一条命令解决但版本跟随发行版只适合快速验证。官方离线安装包不提供 MySQL 驱动装完检查插件目录ls -l $HOME/Qt/5.14.2/gcc_64/plugins/sqldrivers/正常情况下只能看到libqsqlite.so没有libqsqlmysql.so这就是后续所有编译工作的原因。官方二进制包只内置 SQLite 驱动MySQL 客户端库的版本需要跟随目标机器所以驱动必须在部署环境里现编这也解释了为什么 Linux 下 QT 连接 MySQL 的资料里编译驱动永远是第一课。3. 用 qmake 从 QT 源码编译 QMYSQL 驱动驱动编译是整个流程里最容易被版本差异绊倒的一步。QT 5.12 到 5.15 的源码路径和编译方式基本一致到了 QT 6 换成了 CMake这一章以 QT 5.14.2 和 5.15.2 这两个常见版本为准逐条把命令讲清楚。3.1 找到 QT 源码里的 mysql 驱动目录编译 QMYSQL 的前提是手上有 QT 源码。官方离线安装包在安装时勾选 Src 组件源码会放到$HOME/Qt/5.14.2/Src/下面驱动目录在ls $HOME/Qt/5.14.2/Src/qtbase/src/plugins/sqldrivers/目录里能看到 mysql、sqlite、psql 等子目录mysql 目录下有mysql.pro、qsql_mysql.cpp、qsql_mysql_p.h三个关键文件。如果安装时没勾 Src两个补救办法重新跑一次离线安装包勾上 Src 组件或者去官网下载对应版本的 qtbase 源码 tar.xz 包解压目录结构完全一致。源码包解压后如果出现文件名乱码多半是终端语言环境问题用LC_ALLC.UTF-8 tar -xJf qtbase.tar.xz重新解一次即可。QT 6 的驱动源码挪到了qtsql/src/plugins/sqldrivers/mysql构建系统换成 CMake本章命令针对 5.x 系列。如果你的项目锁定 QT 6思路不变命令换成cmake -DCMAKE_PREFIX_PATH$HOME/Qt/6.x.x/gcc_64那一套。3.2 编译命令与 qmake 参数说明在 mysql 驱动目录里执行编译cd $HOME/Qt/5.14.2/Src/qtbase/src/plugins/sqldrivers/mysql $HOME/Qt/5.14.2/gcc_64/bin/qmake mysql.pro \ INCLUDEPATH/usr/include/mysql \ LIBS-L/usr/lib/x86_64-linux-gnu -lmysqlclient make -j$(nproc)参数逐条说明qmake必须用 QT 安装目录里的那个路径是$HOME/Qt/5.14.2/gcc_64/bin/qmake用系统/usr/bin/qmake会生成与目标 QT 版本不匹配的 Makefile编出来的插件加载时报版本错误问题非常隐蔽。INCLUDEPATH/usr/include/mysql告诉编译器去哪找mysql.h。LIBS-L/usr/lib/x86_64-linux-gnu -lmysqlclient指定客户端库所在目录和链接名-L的目录以 2.2 节mysql_config --libs的输出为准。-j$(nproc)并行编译机器核数多时能省不少时间。注意编译驱动用的 qmake 与后面编译业务工程用的 qmake 必须是同一个 QT 安装目录下的二进制混用会生成错误的 Makefile这种错误不看构建日志很难发现。一个常见的意外是 qmake 阶段报Library mysqlclient is not defined。这是 Qt 5.12 之后部分源码包引入的 QMAKE_USE 机制在查询 mysql 库定义查询失败就中断。上面显式传 INCLUDEPATH 和 LIBS 在多数环境能绕过仍报错的话打开mysql.pro以及它 include 的../qsqldriverbase.pri把QMAKE_USE mysql一行注释掉手动补上INCLUDEPATH /usr/include/mysql和LIBS -lmysqlclient再重新 qmake 和 make。编译顺利的话当前目录会出现libqsqlmysql.so以及带版本号的软链接。3.3 安装进插件目录并用 ldd 验证sudo cp libqsqlmysql.so $HOME/Qt/5.14.2/gcc_64/plugins/sqldrivers/ ldd $HOME/Qt/5.14.2/gcc_64/plugins/sqldrivers/libqsqlmysql.so | grep -E mysql|sslldd的输出里应当能看到libmysqlclient.so.21之类的行。如果显示not found说明运行时找不到客户端库两个解决办法把libmysqlclient.so所在目录加进LD_LIBRARY_PATH或者在/etc/ld.so.conf.d/下写一个 conf 文件然后执行sudo ldconfig。复制之前先用find . -name libqsqlmysql.so*确认产物确实生成在驱动目录下很多人卡在这一步是因为 make 输出被前面报错淹没实际驱动根本没编出来。3.4 编译期常见报错对照表报错信息原因处理方式Library mysqlclient is not definedQMAKE_USE 查询 mysql 库定义失败手动注释 QMAKE_USE补 INCLUDEPATH 与 LIBScannot find -lmysqlclient-L路径不对用mysql_config --libs核对路径mysql.h: No such file or directory没装客户端开发库安装 libmysqlclient-dev / mysql-develundefined reference to mysql_*头文件与库版本不一致清理系统里多版本 mysqlclientqmake: could not exec调用的是系统 qmake改用 QT 安装目录下的 qmake 全路径另外注意 QT 安装路径里不要带空格和中文。qmake 对含空格的路径支持不好中文用户名目录在 CI 机器上很容易踩编译能过但插件加载时库路径解析失败报的错看起来像驱动不存在实际是路径问题。4. QSqlDatabase 建立连接最小代码与参数对照驱动就位后连接代码本身并不复杂但连接参数里的 host 写法、端口和授权账号的匹配关系决定了报错是驱动未加载还是权限拒绝。这一章给出一份可以直接跑的最小工程并把 6 个核心连接参数逐个说透。4.1 .pro 里加 QT sql新建一个空目录放两个文件。qt_mysql_demo.pro内容QT sql CONFIG console c11 TARGET qt_mysql_demo SOURCES main.cppQT sql引入的是 QSqlDatabase、QSqlQuery 的头文件和 sql 模块库运行时才去plugins/sqldrivers里找 QMYSQL 插件。如果 .pro 里忘加这一行编译阶段报QSqlDatabase: No such file or directory这时候先检查 .pro 而不是环境。4.2 最小连接代码与逐行说明main.cpp的完整代码#include QCoreApplication #include QSqlDatabase #include QSqlQuery #include QSqlError #include QDebug int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); // 驱动名 QMYSQL 必须与编译好的插件对应 QSqlDatabase db QSqlDatabase::addDatabase(QMYSQL); db.setHostName(127.0.0.1); // 走 TCP避开 unix socket 路径问题 db.setPort(3306); db.setDatabaseName(testdb); db.setUserName(qtuser); db.setPassword(Qt2024); if (!db.open()) { // lastError 是排错的第一现场 qDebug() 连接失败: db.lastError().text(); return 1; } QSqlQuery query(db); if (!query.exec(SELECT VERSION())) { qDebug() 查询失败: query.lastError().text(); return 1; } if (query.next()) qDebug() MySQL 版本: query.value(0).toString(); db.close(); return 0; }代码逻辑说明addDatabase(QMYSQL)的驱动名必须与插件对应db.open()返回 false 时lastError().text()是第一手排错信息比猜测配置强得多SELECT VERSION()用来验证从驱动到服务端的整条链路是否通输出形如8.0.36就说明连接建立成功。编译运行整个工程$HOME/Qt/5.14.2/gcc_64/bin/qmake make ./qt_mysql_demo提示addDatabase不传连接名时注册的是默认连接单连接程序不用特意起名多库多连接场景再用addDatabase(QMYSQL, connName)区分。4.3 6 个连接参数的取值对照方法含义常用值与注意点setHostName主机地址127.0.0.1走 TCPlocalhost走 unix socketsetPort端口默认 3306服务端改过端口必须同步setDatabaseName数据库名必须已存在否则报 Unknown databasesetUserName用户名建议用专用账号别用 rootsetPassword密码与账号匹配setConnectOptions连接选项分号分隔如MYSQL_OPT_RECONNECT1localhost和127.0.0.1的差异值得单独说前者让 MySQL 走/var/run/mysqld/mysqld.socksocket 文件后者走 TCP。如果程序用localhost而 socket 文件不在默认位置报错是Cant connect to local MySQL server through socket改回127.0.0.1用 TCP 是最省事的绕法远程连接则必须用 IP 地址。4.4 创建账号与授权对齐 host 匹配规则在 MySQL 里执行CREATE DATABASE testdb CHARACTER SET utf8mb4; CREATE USER qtuser127.0.0.1 IDENTIFIED BY Qt2024; GRANT ALL PRIVILEGES ON testdb.* TO qtuser127.0.0.1; FLUSH PRIVILEGES;MySQL 的账号匹配是用户加 host 的二元组qtuser127.0.0.1和qtuserlocalhost是两个不同账号。程序用127.0.0.1连接授权就必须写127.0.0.1或%否则报Access denied for user qtuserlocalhost报错信息里的 host 会明确告诉你去改哪一行授权。连不上的另一类常见报错是Cant connect to MySQL server on 127.0.0.1 (111)原因是 mysqld 没启动或bind-address只绑了本机网卡。先systemctl status mysql看服务状态再看/etc/mysql/mysql.conf.d/mysqld.cnf里的bind-address需要远程访问时改成实际服务 IP 或注释掉这行。5. MySQL 驱动自检脚本与 utf8mb4 中文编码收尾驱动编译完、代码能跑通之后还有两件事值得固化下来一个是换机器部署时快速确认驱动状态的自检手段一个是中文字符集配置。这两件事都做掉Linux 下 QT 连接 MySQL 的链路才算真正闭环。5.1 用 QT_DEBUG_PLUGINS 定位驱动加载失败QT 内置了插件调试开关运行程序前加上环境变量就能看到每个插件的加载日志QT_DEBUG_PLUGINS1 ./qt_mysql_demo如果日志里出现Cannot load library ... libmysqlclient.so ... not found问题在依赖库缺失而不是插件没安装回到 3.3 节处理LD_LIBRARY_PATH。如果日志显示QLibraryPrivate::loadPlugin failed多半是路径里有空格或权限不对。把自检步骤写成一个脚本部署新机器时先跑一遍#!/bin/bash QT_PLUGINS$HOME/Qt/5.14.2/gcc_64/plugins/sqldrivers ls -l $QT_PLUGINS/libqsqlmysql.so ldd $QT_PLUGINS/libqsqlmysql.so | grep mysqlclient QT_DEBUG_PLUGINS1 ./qt_mysql_demo脚本跑完ldd输出里有libmysqlclient且程序正常退出驱动链路就通了。再配合一个三行程序列出当前 QT 环境认得的全部驱动#include QCoreApplication #include QSqlDatabase #include QDebug int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); qDebug() QSqlDatabase::drivers(); return 0; }输出列表里能看到QMYSQL才算驱动注册成功只有QSQLITE说明插件路径根本没被加载。5.2 字符集统一到 utf8mb4而不是等到乱码再改中文字段出现问号或乱码九成是连接层字符集没指定。最可靠的做法是把字符集写进连接选项而不是每次连接后手动执行SET NAMESdb.setConnectOptions(MYSQL_OPT_RECONNECT1;MYSQL_SET_CHARSET_NAMEutf8mb4);MYSQL_SET_CHARSET_NAME等价于连接建立后自动执行SET NAMES utf8mb4MYSQL_OPT_RECONNECT让断开的连接自动重连适合长时间驻留的桌面程序。建表时也统一指定CREATE TABLE user_info ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(64) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;最后用命令行核对服务端默认字符集mysql -uqtuser -p -e SHOW VARIABLES LIKE character_set_server。输出与连接层不一致时回到 5.2 重新设置连接选项服务端、连接层、表结构三处都对齐到 utf8mb4中文读写乱码就能在写业务代码之前先被排除掉。本文还有配套的精品资源点击获取