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的密碼,一切好轉起來。