QT及嵌入式FireBird入门

来源:互联网 发布:学珠宝设计软件 编辑:程序博客网 时间:2024/04/27 16:45
 本文逐步介绍QT,VS和FireBird

简介

本文逐步介绍QT,VS和FireBird.适用于打算使用嵌入式FireBird的QT开发者以及QT新手.

在我写这篇文档的时候,有关本文涉及的话题还在大量的讨论,所以我希望本文能对大家有所帮助.

本文讨论的内容:

1.  安装QT SDK,并与VS进行配置整合.

2.  Building IBase插件.

3.  使用代码创建一个数据库并设置其连接.

4.  同时也讨论数据库的用户名和密码问题.

5.  创建一个简单的查询及调用存储过程.

开发配置环境

下面描述的范例基于QT 4.5.2 LGPL. 

按如下步骤设置开发环境.

1. 安装QT SDK:

1.  有足够的磁盘空间 (要编译所有库和范例需要2-3 GB,否则1.5 GB).

2.  安装SDK:  QTSDK 4.5.2
推荐不要修改默认的安装路径(或在其他盘符的相同路径下,如"D:\").

3.  创建环境变量"QTDIR"值为"C:\Qt\2009.03\qt\" (步骤2为默认).

2. 在VS2005/2008下Build QT

1) 启动"VS 2005 Command Prompt"  (开始菜单)

2) 在控制台上设置当前目录QTDIR = "C:\Qt\2009.03\qt\"

3) 使用下面命令行启动"configure.exe":

configure.exe  -plugin-sql-ibase.(注意后面的参数没有空格)

可使用下面命令查看每个参数的详细信息:

configure.exe  -help

4) 然后控制台询问:要使用哪个版本的QT?(Which edition of Qt do you want to use?)选择Open Source版本.

按Y键确认授权信息.

5) 现在需要等一会才能将VCProj文件和主解决方案创建出来.最后在C:\Qt\2009.03\qt目录下生成projects.sln解决方案文件

3. 安装VS的QT插件

1) 关闭所有VS应用.

2) 启动qt-vs-addin-1.0.2.exe 安装程序

3) 启动VS,点击QT选项("QT->QT Options").点击并输入QT版本号名称如"QT 4.5.2".这里的名称并不重要,但是其将存储在项目文件中,因此其他开发者可能在生成项目的时候报错: ("No such QT version is found on this machine" or something like this).

指定Qt路径,本例为$(QTDIR)("C:\Qt\2009.03\qt\"). 最后选择新创建的记录"QT 4.5.2"作为默认版本.

4) 不需要生成全部项目.只需要生成:

·         QtCore

·         QtGUI

·         QtSQl

·         QMain

注意:  Win32静态库和QT库对"Treat wchar_t as Built-In"属性有不同的设置.如果想在QT应用程序中使用Win32静态库,需要将这个属性去除或改为No("Treat wchar_t as Built-In Type"为"No(/Zc:wchar_t-)".

要关掉这个选项,需要在步骤2之前进行如下操作:

·         打开qmake.conf文件,可在QTDIR/mkspecs/win32-msvc2005/qmake.conf目录中找到.我使用VS2005因此选择子目录win32-msvc2005中的文件.如果你使用其他版本要选择相应的目录文件.

·         在这个文件中修改QMAKE_CFLAGS标记,删除-Zc:wchar_t-.

4. 安装 FireBird

Firebird下载地址– FireBird.

5. 生成IBase插件

进入目录$(QTDIR)\src\plugins\sqldrivers\ibase ,并在Debug和Release模式下Build项目.

 生成之前修改如下项目属性:

·         在 C/C++/General->Additional Include Directories 添加包含路径(如C:\Program Files\Firebird\Firebird_2_1\include)

·         在Linker/General -> Additional Library Directories 添加FireBird库路径.(如C:\Program Files\Firebird\Firebird_2_1\lib)

·         要生成IBase项目我们需要修正链接库名称(Linker/Input->Additional Dependencies),将gds32_ms.lib调整为fbclient_ms.lib .库包含在FireBird包中.

嵌入式服务器下载地址: FireBird Embedded 2.1.3 Release

·         修改fbembed.dll文件名为fbclient.dll.

连接到存在的数据库

在设置数据库连接之前,我们首先需要加载QIBASE插件.如果你要使用插件并手动加载,可以使用如下代码(假定插件与Exe文件同目录).

 …

    if(!pluginLoader_.isLoaded())

    {

        pluginLoader_.setFileName(QApplication::instance()->applicationDirPath() +

 QDir::separator() + qtIBasePluginName_);

       

        if (!pluginLoader_.load())

        {           

            //// Loading SQL Driver failed.;

            isInitialized_ = false;

            return false;

        }

    }

 

    QObject* object = pluginLoader_.instance();

 

    if (object == NULL)

    {           

        //Loading SQL Driver Instance failed.;

 

        pluginLoader_.unload();

        return false;

    }

 

    QSqlDriverPlugin* plugin = qobject_cast<QSqlDriverPlugin*>(object);

 

    if (plugin == NULL)

    {           

        //QSqlDriverPlugin == NULL;

        pluginLoader_.unload();

        return false;

    }

 

    driver_ = plugin->create("QIBASE");

 

    if (driver_ == NULL)

    {           

        //Loading QIBASE Driver Instance failed.;

        pluginLoader_.unload();

        return false;

    }

 

    isInitialized_ = true;

 

    return isInitialized_;

 

FireBird支持插件加载后,就可以开始连接数据库了.

    connectionName_ = "Connection_1";

           

    QSqlDatabase database;

 

    //Adding database (DRIVER);

    database = QSqlDatabase::addDatabase(driver_, connectionName_);

 

    //Check Valid database.;

    if (!database.isValid())

    {

        QString lastError = database.lastError().text();

        //Database is not valid

        return false;

    }

 

    //Set database configurations.;

// filePath = ":D:\FireBirdAndQT\debug\New.FDB";

// userName = "Serg";

// password = 12345;

// connectionString_ = "server type=Embedded; auto_commit=True;

// auto_commit_level=4096; connection lifetime=1; DataBase=\"%1\"";

    database.setDatabaseName(filePath);

    database.setUserName(userName);

    database.setPassword(password);

 

    QString connectionString = QString(connectionString_).arg(filePath);

    database.setConnectOptions(connectionString);

 

    bool result = false;

   

    //"Openning database. Driver PTR == %d", (int)database.driver();

    result = database.open();

 

    if(!result)

    {

        QString lastError = database.lastError().text();       

        lastError_ = (uint)database.lastError().number();       

    }

 

希望可以对QSqlDatabase如下几个属性加以注意:

    database.setDatabaseName(filePath);

    database.setUserName(userName);

    database.setPassword(password);

 

 

    QString connectionString = QString(connectionString_).arg(filePath);

    database.setConnectOptions(connectionString);

 

 

登录名,密码和完整路径需要包含在连接字符串中,但是有如下几个问题:我将上面提到的几个设置加入到连接字符串中,而没有使用set…()函数,我发现这些值没有设置到数据库对象.

使用代码创建FireBird数据库

使用代码创建数据库须如下代码:

bool FireBirdDatabase::Create(const QString& filePath, const QString& userName, const QString& password)

{

 

    if (!isInitialized_)

    {

        Initialize();

    }

 

    if (QFile::exists(filePath))

    {

        return false;

    }

 

    databasePath_ = filePath;

 

    QString queryString;

    queryString += "CREATE DATABASE";

    queryString += " \'" + filePath + "\'";

    queryString += " USER \'" + userName + "\'";

    queryString += " PASSWORD \'" + password + "\'";

    queryString += " DEFAULT CHARACTER SET UNICODE_FSS";

 

    ISC_STATUS_ARRAY status;

    isc_db_handle   databaseHandle = NULL;

    isc_tr_handle   transactionHandle = NULL;

 

    unsigned short g_nFbDialect = SQL_DIALECT_V6;

 

    if (isc_dsql_execute_immediate(status, &databaseHandle, &transactionHandle, 0, queryString.toStdString().c_str (), g_nFbDialect, NULL))

    {

        long SQLCODE=isc_sqlcode(status);

        return false;   

    }

 

    isc_commit_transaction( status, &transactionHandle );

 

    if (databaseHandle != NULL)

    {

        ISC_STATUS_ARRAY status;

        isc_detach_database(status, &databaseHandle);

    }

 

    return true;

 

为什么使用isc_dsql_execute_immediate()函数创建数据库?答案是我不能使用其他方式.一些供应商允许如下方式创建数据库:

QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");

 db.setDatabaseName(":memory:");

    if (!db.open())

{

QMessageBox::critical(0, qApp->tr("Cannot open database"),

            qApp->tr("Unable to establish a database connection.\n"

                     "This example needs SQLite support. Please read "

                     "the Qt SQL driver documentation for information how "

                     "to build it.\n\n"

                     "Click Cancel to exit."), QMessageBox::Cancel);

        return false;

}

 

但是 通常QT版本和IBASE驱动不支持这种方式.

更多信息可以查看QT范例 (QTDIR\examples\sql\Connection.h).

注意: 小心- FireBird只支持ASCII编码.如果你的路径中包括Unicode字符isc_dsql_execute_immediate函数将报错.

数据库查询

简单的从数据库中查询.

void DatabaseModel::SelectJobs(QStringList& jobs )

{

    QSqlQuery query = QSqlQuery(fireBirdDatabase_.CreateQuery());

 

    QString preparedString = "SELECT JOB_NAME FROM TBL_JOBS";

 

    query.prepare(preparedString);

 

    if (!query.exec())

    {

        QString err = query.lastError().text();        

      

        throw std::runtime_error("Error executing Query.");

    }   

 

    while (query.next())

    {

        QSqlRecord record = query.record();

        jobs.append(record.value(0).toString());

       

    }

}

fireBirdDatabase_.CreateQuery()实现如下:

  {

  return  QSqlQuery(QSqlDatabase::database(connectionName_));

  }

 

如何调用存储过程?

考虑一个典型的范例-调用向数据库中添加一条记录的存储过程.

存储过程包含的参数:一个字符串位置名称,整数工资,BLOB的描述信息.

存储过程返回新纪录的ID. 

    {

      …

    QByteArray description("Test description");

    int salary = 1200;

    jobName = "tester";

    QSqlQuery query(fireBirdDatabase_.CreateQuery());

            bool result = query.prepare("EXECUTE PROCEDURE SP_INSERT_JOB (?, ?, ?)");

                     query.addBindValue(jobName);

                     query.addBindValue(salary);

    query.addBindValue(description);   

 

    if (!query.exec())

    {

        QString err = query.lastError().text();           

        throw std::runtime_error("Error executing Query.");

    }   

    query.next();

    int jobID = query.value(0).toUInt();

      …

    }

结论

希望本文可以帮助你:

为进一步工作配置QT环境.

为使用FireBird生成插件.

连接到已存在的数据库或使用程序新建一个.

执行各种查询.

我以将测试数据库和代码上传.

查看数据库可以使用如下客户端工具:

·         IBExpert

·         FlameRobin

测试数据库用户名和密码分别为Serg,12345.

有用的连接

·         Firebird database.

·         FlameRobin (开源管理工具).

·         IBExpert (administration tool, free Personal Edition download).

·         Other Firebird tools.

·        QTSDK 4.5.2

原创粉丝点击