Qt 访问 MySQL

来源:互联网 发布:天敏网络机顶盒 编辑:程序博客网 时间:2024/06/02 08:11

Qt 里访问 MySQL 是件很简单的事,但也有可能很不简单。说其简单是因为熟悉的人都知道只需要有 MySQL 的驱动插件和复制 MySQL 的动态链接库到可识别的环境变量的路径下即可,对于不熟悉的人来说,看到 Qt 给我们的错误信息简单到QMYSQL driver not loaded,从这一句简单的提示里却找不到任何头绪,不知道应该怎么做,在网络上搜索了很多文章,照着做有的人问题解决了,有的人试过了很多种方法问题仍然存在。在这一节里,我们会一步一步的来分析,解决访问 MySQL 的问题。访问其他数据库也可以用同样的方法解决。

Qt 访问 MySQL 需要 2 个动态链接库文件,一个是 Qt 自己的 MySQL 驱动插件,另一个是 MySQL 提供的动态链接库,缺一不可。在程序里指定要访问的数据库为 MySQL,Qt 会自动的加载MySQL 驱动插件,其实现依赖于MySQL 的动态链接库访问 MySQL。

MySQL 的驱动插件

Qt 5 的 SDK 默认提供了编译好的 MySQL 驱动插件,位于 plugins/sqldrivers(Mac OS 下为 libqsqlmysql.dylib,Windows 下为 qsqlmysql.dll)。但如果用的是 Qt 4,很不幸, 需要我们自己编译 MySQL 的驱动插件,网络上有很多关于编译MySQL 的驱动插件的文章,而且不同的系统,不同的编译器中步骤有所区别,需要相当大的篇幅才能讲清楚,在这里就不重复赘述了。

MySQL 的动态链接库(MySQL 社区版下载地址)

  • OS X 下载解压版解压,在目录 lib 里可以找到 MySQL 的动态链接库 libmysqlclient.18.dylib
  • Windows 下载解压版解压,在目录 lib 里可以找到 MySQL 的动态链接库 libmysql.dlllibmysqld.dll

准备数据库环境

假设在我们的电脑中已经准备好了如下的环境:

  1. 安装了 MySQL
  2. 在 MySQL 中创建了一个数据库名为 qt
  3. 在数据库 qt 中创建表 user
CREATE TABLE `user` (  `id` int(11) NOT NULL AUTO_INCREMENT,  `username` varchar(256) NOT NULL,  `password` varchar(256) NOT NULL,  `email` varchar(256) DEFAULT NULL,  `mobile` varchar(32) DEFAULT NULL,  PRIMARY KEY (`id`))

表中的数据如下:

idusernamepasswordemailmobile1Alicepassw0rdNULLNULL2BobPassw0rdNULLNULL3JoshPa88w0rdNULLNULL

访问 MySQL 数据库

接下来用 Qt 访问 MySQL,输出表 user 中所有的 username,如果不出错的话,输出如下:

Alice
Bob
Josh

Qt 访问 MySQL 的步骤:
  1. 加载MySQL 驱动
  2. 设置 MySQL 所在电脑的 IP
  3. 设置数据库名
  4. 设置用户名
  5. 设置密码
  6. 打开数据库
  7. 创建 query 对象,执行 SQL 查询语句
  8. 遍历 query 查询到的结果
#include <QCoreApplication>#include <QDebug>#include <QSqlDatabase>#include <QSqlQuery>#include <QSqlError>#include <QPluginLoader>void accessMySql();int main(int argc, char *argv[]) {    QCoreApplication app(argc, argv);    accessMySql();    return app.exec();}void accessMySql() {    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "Connection_Name");    db.setHostName("127.0.0.1");    db.setDatabaseName("qt");    db.setUserName("root");    db.setPassword("root");    if (!db.open()) {        qDebug() << "Connect to MySql error: " << db.lastError().text();        return;    }    QSqlQuery query(db);    query.exec("SELECT * FROM user");    while (query.next()) {        qDebug() << query.value("username").toString();    }}

不幸的是,程序运行的结果没有输出所有的 username,而是输出下面的错误信息:

QSqlDatabase: QMYSQL driver not loaded
QSqlDatabase: available drivers: QSQLITE QMYSQL QMYSQL3 QPSQL QPSQL7
Connect to MySQL error: Driver not loaded Driver not loaded

等等,这是肿么了,竟然报错,我们的代码和别人的是一样的啊,再检查一遍,Qt 的帮助文档里也是这样做的,难道是人品问题?

明明提示我们可用的数据库驱动里就有 MySQL 的驱动啊,而且我们也看到了在plugins/sqldrivers目录里确实有 MySQL的驱动插件,为什么会报错呢?这貌似不科学!如果我们只是盯着看QMYSQL driver not loaded,这错误提示也太简单了,当然想不明白。

还记不记得开始的时候说过,访问 MySQL 需要 2 个动态链接库文件,一个是 MySQL 驱动插件,另一个是其依赖的MySQL 的动态链接库,缺一不可。

  1. QSqlDatabase: available drivers 里有 QMYSQL,说明我们的环境中已经有了MySQL 驱动插件
  2. 但是,什么是MySQL 的动态链接库?应该放在哪里?
    • MySQL 的动态链接库是 MySQL 提供给我们编程访问 MySQL 的库文件,在 MySQL 的 lib 目录里有。
    • 应该放在哪里?
      我们可以用下面的程序来加载MySQL 驱动插件,如果加载出错,原因有可能为依赖的库文件找不到,库文件的版本不兼容等,程序会给出详细的错误信息,依据这个线索我们就能够找出具体是什么错误,从而很容易的解决问题了(这个方法也可以用来加载其他的 Qt 插件)。
#include <QSqlDatabase>#include <QSqlQuery>#include <QSqlError>#include <QPluginLoader>void loadMySqlDriver();int main(int argc, char *argv[]) {    QCoreApplication app(argc, argv);    loadMySqlDriver();    return app.exec();}void loadMySqlDriver() {    QPluginLoader loader;    // MySQL 驱动插件的路径    loader.setFileName("/Users/Biao/Qt5.4.0/5.4/clang_64/plugins/sqldrivers/libqsqlmysql.dylib");    qDebug() << loader.load();    qDebug() << loader.errorString();}

OS X 里运行程序,输出如下:

false
Cannot load library /Users/Biao/Qt5.4.0/5.4/clang64/plugins/sqldrivers/libqsqlmysql.dylib:
(dlopen(/Users/Biao/Qt5.4.0/5.4/clang
64/plugins/sqldrivers/libqsqlmysql.dylib, 5):Library not loaded: /opt/local/lib/mysql55/mysql/libmysqlclient.18.dylib
Referenced from: /Users/Biao/Qt5.4.0/5.4/clang_64/plugins/sqldrivers/libqsqlmysql.dylib
Reason: image not found)

我们来分析一下 OS X 中的错误:loader.load() 如果加载成功则返回 true,返回 false 表明加载失败。loader.errorString() 给出了插件加载失败的具体原因:找不到 /opt/local/lib/mysql55/mysql/libmysqlclient.18.dylib。

好了,既然知道了具体的错误原因,那么接下来就好办了,从 MySQL 的 lib 目录里复制 libmysqlclient.18.dylib 到 /opt/local/lib/mysql55/mysql/ (没有这个目录?好说,我们自己手动创建就可以了),然后再次运行程序,这次输出:

true
Unknown error

loader.load() 返回了 true,MySQL 驱动插件加载成功了,看来这个问题很好解决嘛。快快运行上面访问 MySQL 的程序,见证奇迹的时刻到了:

Alice
Bob
Josh

Windows 里运行程序,输出如下:

注意:修改 MySQL 驱动插件的路径为你的系统里相应的路径,如 loader.setFileName(C:/Qt/Qt5.4.0/5.4/mingw491_32/plugins/sqldrivers/qsqlmysqld.dll);

false
Cannot load library C:/Qt/Qt5.4.0/5.4/mingw491_32/plugins/sqldrivers/qsqlmysqld.dll:找不到指定的模块

很不幸,这里的错误说明没有 OS X 里那么清晰,如果不熟悉,还是找不到问题的根源。如果我们在 loader 中加载一个不存在的 dll 呢?如:loader.setFileName(C:/Qt/Qt5.4.0/5.4/mingw491_32/plugins/sqldrivers/qsqlmysqldddd.dll),这时输出

false
The shared library was not found.

由此看来加载 MySQL 驱动出错不是找不到驱动插件 qsqlmysqld.dll,而是找不到 qsqlmysqld.dll 依赖的 DLL. 把 libmysql.dll 和 libmysqld.dll 复制到 exe 文件所在目录(如下图),然后再运行程序,这时 MySQL 驱动插件就加载成功了,输出

true
Unknown error

Linux 中的输出信息和 OS X 几乎一样,这里就不再赘述了

至此,Qt 访问 MySQL 大功告成,接下来诸位想用 Qt 对 MySQL 做些什么事,此处省略一万字……

0 0