qt5.6.3下使用firebird
有人把firebird比作数据库界的瑞士军刀,想学习一下其在QT5.6中的使用,于是便开始了一场自己挖坑,自己埋的旅程。
环境说明:win7 64位+QT5.6 mingw4.9 32位(好像官网上也没有64位,当然mingw也是32位的)+firebird 64位。再介绍一下中间人:Mysql5.7 64位版本(本文重点是介绍QT+FireBird,为什么要加入Mysql,切看下文)
一、先下载firebird。网址:www.firebirdsql.org。我们选择最新版本3.0.4,64位,zip格式的。当然您最好把32位的也一并下载。因为……,以后会用得着,然后分别解压,鄙人的目录分别是e:\firebird64和e:\firebird32。
二、按照网上资料,开始编译QIBASE,目的是生成qsqlibase.dll和qsqlibased.dll,首先进入E:\Qt\Qt5.6.3\5.6.3\Src\qtbase\src\plugins\sqldrivers\ibase,找到ibase.pro,打开它,修改成以下内容:
TARGET = qsqlibase
SOURCES = main.cpp
OTHER_FILES += ibase.json
INCLUDEPATH += E:\firebird32\include
LIBS += E:\firebird32\lib\fbclient_ms.lib
include(../../../sql/drivers/ibase/qsql_ibase.pri)
PLUGIN_CLASS_NAME = QIBaseDriverPlugin
include(../qsqldriverbase.pri)
请注意上面的红色代码部分:尽量放在include的前面。因为什么呢?我们看qsql_ibase.pri,这个文件引入了另外两个文件,在另外两个文件中需要用到INCLUDEPATH中的ibase.h,如果次序不对,可能会出现无法找到ibase.h的错误。
三、填坑1:上面这个INCLUDEPATH,很关键,当初哥们在这里整整填了一天的坑。刚开始只下载了firebird64位版本,无论怎么编译都通不过。直接放弃。改用Mysq,心想Mysql是QT5.6原生支持。如何查看QT5.6支持哪些数据库?一是可以到下面目录中查看 :
E:\Qt\Qt5.6.3\5.6.3\mingw49_32\plugins\sqldrivers。里面有哪些dll,QT就支持哪些,不用编译。二者当然也可以在程序中通过以下方法来查看:
#include <QtSql/QSqlDatabase>
#include <QtSql/QSqlError>
#include <QDebug>
#include <QStringList>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QStringList lists=QSqlDatabase::drivers();
qDebug()<<lists.join("-");
return a.exec();
}
结果,在使用mysql时,程序却提示QMYSQL找不到。把libmysql复制到mingw49\bin文件夹中,仍然不行。经查找资料,找到答案,原来需要使用32位版本的libmysql,于是从到mysql官网找到32位的libmysql.dll,复制到mingw49_32\bin文件夹中,发现QT可以操作mysql了,还可以直接使用64位版本mysql生成的数据库。在此,明白了先前为什么编译firebird不通过的原因:你引入的是64位的库文件及头文件,当然无法用32位的mingw32-make编译啦。于是哥们又重新找出32位的firebird,按照第二步提到的内容重新编译。哈,通过,生成了qsqlibase.dll和qsqlibased.dll。此时这两个Dll位于E:\Qt\Qt5.6.3\5.6.3\Src\qtbase\plugins\sqldrivers之下。再把32位firebird文件夹中的fbclient.dll复制到mingw49的bin文件夹中,发现可以使用QIBASE模块啦。
编译方法如下:(为方便操作,把qmake和mingw32-make放入到系统环境变量中)
进入E:\Qt\Qt5.6.3\5.6.3\Src\qtbase\src\plugins\sqldrivers\ibase\
qmake ibase.pro
mingw32-make
四、填坑2。有了dll,以为就万事大吉,按照网上资料,开始打开数据库进行操作,代码如下:
QSqlDatabase db=QSqlDatabase::addDatabase("QIBASE");
db.setUserName("sysdba");
db.setPassword("masterkey");
db.setDatabaseName("D:\\SLj.FDB");
if(!db.isValid())
{
QString lastError = db.lastError().text();
qDebug()<<lastError;
}
else
qDebug()<<"database connect success";
if(db.open())
{
qDebug()<<"database open success";
db.close();
}
else
{
qDebug()<<"database open error:"<<db.lastError().text();
db.close();
}
此时程序会提示:install incomplete please read compatibility chapter之类的信息。意思是说安装不完整,请阅读手册兼容性部分。哥们哪有时间去阅读啊,直接网上找,看别人是怎么解决不就成了。结果查了一天也没找出个结果。没办法,只好找官网上老老实实看手册。在各类guide中都没找到,最后看release notes吧。哈,果然在第12部分的Initializing the Security Database找到了答案,我们看一下官网是怎么说的:
By default, Firebird 3 is configured for the new authentication model which uses SRP to work with user passwords and generate unique session identifiers for traffic encryption. The security database (security3.fdb
) has no predefined users. This is intentional.
啥意思,从3.0开始,默认用户名还是sysdba,但密码不再是masterkey啦,成了一个加密的随机字符串。上面的操作当然无法打开数据库啦。再看下面。
The SQL user management commands will work with any open database. Because the sample database employee.fdb
is present in your installation and already aliased in databases.conf
, it is convenient to use it for the user management task.
-
Stop the Firebird server. Firebird 3 caches connections to the security database aggressively. The presence of server connections may prevent isql from establishing an embedded connection.
-
In a suitable shell, start an isql interactive session, opening the employee database via its alias:
> isql -user sysdba employee
-
Create the SYSDBA user:
SQL> create user SYSDBA password 'SomethingCryptic'; SQL> commit; SQL> quit; 好了,按照这个步骤,重新设置firebird的密码,一切好转起来。