环境:ubuntu18.04.2 LTS + QT5.12.3 + MySQL5.7.26
geek@geek-ubuntu:~/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers$ cat /proc/version
Linux version 4.15.0-50-generic (buildd@lcy01-amd64-013)
(gcc version 7.3.0 (Ubuntu 7.3.0-16ubuntu3)) #54-Ubuntu SMP Mon May 6 18:46:08 UTC 2019
geek@geek-ubuntu:~/software/$ sudo mysql --version
mysql Ver 14.14 Distrib 5.7.26, for Linux (x86_64) using EditLine wrapper
问题描述:
QSqlDatabase: MYSQL driver not loadedQSqlDatabase:
available drivers: QSQLITE QMYSQL QMYSQL3 QODBC QODBC3 QPSQL QPSQL7
问题定位:
(1)查看目前安装的QT中MYSQL数据库驱动的共享库依赖关系
geek@geek-ubuntu:~/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers$ ldd libqsqlmysql.so
linux-vdso.so.1 (0x00007ffcef589000)
libmysqlclient.so.18 => not found
libQt5Sql.so.5 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libQt5Sql.so.5 (0x00007fc71a7d6000)
libQt5Core.so.5 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libQt5Core.so.5 (0x00007fc71a043000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fc719cba000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc7198c9000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fc7196ac000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc7194a8000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc719289000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc718eeb000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fc718cd3000)
libicui18n.so.56 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libicui18n.so.56 (0x00007fc71883a000)
libicuuc.so.56 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libicuuc.so.56 (0x00007fc718482000)
libicudata.so.56 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libicudata.so.56 (0x00007fc716a9f000)
libgthread-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0 (0x00007fc71689d000)
libglib-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007fc716586000)
/lib64/ld-linux-x86-64.so.2 (0x00007fc71b243000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007fc716314000)
(2) 查看本地安装的MYSQL数据库驱动共享库版本
geek@geek-ubuntu:~/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers$ cd /usr/lib/x86_64-linux-gnu/
geek@geek-ubuntu:/usr/lib/x86_64-linux-gnu$ ll | grep mysqlclient
-rw-r--r-- 1 root root 5733812 4月 26 02:10 libmysqlclient.a
lrwxrwxrwx 1 root root 20 4月 26 02:10 libmysqlclient.so -> libmysqlclient.so.20
lrwxrwxrwx 1 root root 25 4月 26 02:10 libmysqlclient.so.20 -> libmysqlclient.so.20.3.13
-rw-r--r-- 1 root root 4244768 4月 26 02:10 libmysqlclient.so.20.3.13
注意:对比1和2的结果,发现本地的libmysqlclient.so 和qt mysql驱动库依赖的版本不一致,是导致其无法正常运行的原因。网上有很多基于现有的libmysqlclient.so 创建libmysqlclient.so.18软链接的方案,其实都是错误的做法。
解决方案:
1. 安装QT源代码。
QT安装包提供了源代码,安装QT时可以选择安装源代码,也可以单独到QT官方网站下载源代码。
2. 安装依赖库
sudo apt-get install mysql-client libmysqlclient-dev
这一步是为了安装MYSQL的头文件和libmysqlclient.so库,如果系统有安装过mysql,可能以上依赖已经安装在系统中。安装完成以后mysql的头文件位置一般在/usr/include/mysql, 而共享库在下面几个目录其中:/usr/lib/mysql/ ,/usr/local/lib,/usr/liib/x86_64-linux-gnu。
可通过以下命令定位libmysqlclient.so的位置:
sudo updatedb #更新ubuntu的文件数据库,it may take a long time
sudo locate libmysqlclient.so
3. 编译安装QT MySQL驱动包
(1)进入qt源代码路径下的mysql目录(这里的目录因人而异,是你本地安装QT源代码的目录,我这里是/home/geek/software/Qt5.12.3/5.12.3/Src/qtbase/src/plugins/sqldrivers/mysql,其中/home/geek/software/Qt5.12.3是QT的安装目录)。
(2)使用QT自带的qmake命令编译该工程。
sudo /home/geek/software/Qt5.12.3/5.12.3/gcc_64/bin/qmake "INCLUDEPATH+=/usr/include/mysql" "LIBS+=-L/usr/lib/x86_64-linux-gnu/ -lmysqlclient" mysql.pro
make && make install
注意:这里可能遇到两类问题,如下:
(i)类似于qtsqldrivers-config.pri文件找不到的问题:eg. Cannot read /home/geek/software/Qt5.12.3/5.12.3//Src/qtbase/src/plugins/sqldrivers/qtsqldrivers-config.pri: No such file or directory.
解决方案:修改上一层目录(这里也就是/home/geek/software/Qt5.12.3/5.12.3/Src/qtbase/src/plugins/sqldrivers)的qsqldriverbase.pri文件中的内容,如下:
QT = core core-private sql-private
# For QMAKE_USE in the parent projects.
#include($$shadowed($$PWD)/qtsqldrivers-config.pri)
include($$shadowed($$PWD)/configure.pri)
PLUGIN_TYPE = sqldrivers
(ii)类似于mysql 库文件找不到的问题,eg:project ERROR: Library 'mysql' is not defined.
解决方案:修改当前目录(这里也就是/home/geek/software/Qt5.12.3/5.12.3/Src/qtbase/src/plugins/sqldrivers/mysql)的mysql.pro文件内容,如下:
TARGET = qsqlmysql
HEADERS += $$PWD/qsql_mysql_p.h
SOURCES += $$PWD/qsql_mysql.cpp $$PWD/main.cpp
#把mysql.pro中的 QMAKE_USE += mysql用#注释掉
#QMAKE_USE += mysql
OTHER_FILES += mysql.json
PLUGIN_CLASS_NAME = QMYSQLDriverPlugin
include(../qsqldriverbase.pri)
(3)如果遇到步骤2中遇到的问题,解决完以后重新执行步骤1的编译命令。最后会在QT的plugins/sqldrivers目录下(这里是/home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers)找到编译好的mysql共享库文件。
geek@geek-ubuntu:~/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers$ ll
总用量 2668
drwxrwxr-x 2 geek geek 4096 5月 18 12:30 ./
drwxrwxr-x 34 geek geek 4096 5月 17 11:38 ../
-rwxrwxr-x 1 geek geek 1239408 4月 9 16:22 libqsqlite.so*
-rwxr-xr-x 1 geek geek 103168 5月 18 12:29 libqsqlmysql.so*
-rw-r--r-- 1 geek geek 1138264 5月 18 12:29 libqsqlmysql.so.debug
-rwxrwxr-x 1 geek geek 119352 4月 9 16:21 libqsqlodbc.so*
-rwxrwxr-x 1 geek geek 112440 4月 9 16:21 libqsqlpsql.so*
(4)查看编译完成的最新版本的mysql驱动库的依赖树结构,如下:
geek@geek-ubuntu:~/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers$ ldd libqsqlmysql.so
linux-vdso.so.1 (0x00007ffdef9d6000)
libmysqlclient.so.20 => /usr/lib/x86_64-linux-gnu/libmysqlclient.so.20 (0x00007f44af9ce000)
libQt5Sql.so.5 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libQt5Sql.so.5 (0x00007f44af786000)
libQt5Core.so.5 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libQt5Core.so.5 (0x00007f44aeff3000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f44aec6a000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f44ae879000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f44ae65c000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f44ae458000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f44ae239000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f44ade9b000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f44adc83000)
libicui18n.so.56 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libicui18n.so.56 (0x00007f44ad7ea000)
libicuuc.so.56 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libicuuc.so.56 (0x00007f44ad432000)
libicudata.so.56 => /home/geek/software/Qt5.12.3/5.12.3/gcc_64/plugins/sqldrivers/./../../lib/libicudata.so.56 (0x00007f44aba4f000)
libgthread-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libgthread-2.0.so.0 (0x00007f44ab84d000)
libglib-2.0.so.0 => /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0 (0x00007f44ab536000)
/lib64/ld-linux-x86-64.so.2 (0x00007f44b01f3000)
libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007f44ab2c4000)
和系统版本的libmysqlclient.so 一致。
至此,基于QT源代码编译出适合本地环境的mysql驱动包操作完成。
下面贴上main.cpp测试代码,仅供参考:
// main.cpp
#include
#include
#include
#include
#include
#include
int main(int argc, char *argv[]) {
std::cout << "Hello, World!" << std::endl;
qDebug() << QCoreApplication::libraryPaths();
QCoreApplication app(argc, argv);
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("hotel");
db.setUserName("geek");
db.setPassword("geek");
if (!db.open()) {
qDebug() << "Failed to connect to mysql";
} else {
qDebug() << "open success!";
}
//create the query object
QSqlQuery query(db);
query.exec("create table student(id int primary key, name varchar(20))");
query.exec("insert into hotel.student values(1, 'first')");
query.exec("insert into hotel.student values(2, 'second')");
query.exec("update hotel.student set name='zhang' where id=1");
query.exec("delete from hotel.student where id >= 2");
query.exec("alter table hotel.student add address varchar(60)");
query.exec("alter table hotel.student add address123 varchar(100)");
query.exec("alter table hotel.student add age tinyint unsigned after name");
query.exec("alter table hotel.student drop address123");
query.exec("alter table hotel.student change name name varchar(30)");
query.exec("alter table hotel.student rename hotel.student1");
query.exec("alter table hotel.student1 rename hotel.student");
query.exec("select * from hotel.student where id > 0");
while (query.next()) {
quint32 id = query.value(0).toInt();
QString name = query.value(1).toString();
QString age = query.value(2).toString();
QString address = query.value(2).toString();
qDebug() << id << " ," << name << " ," << age << " ," << address;
}
query.exec("drop table hotel.student");
db.close();
return app.exec();
}