使用IBPP在C++中操作FireBird/Interbase数据库
FireBird是一种小巧的关系型数据库,它有多种版本,包括服务器版(像MySQL),单机版(像Access)以及嵌入式(像SQLite)。而且不管是服务器版还是嵌入式版它都完整支持视图、触发器、存储过程等SQL高级特性。
问题是它提供的C API “不太友好”,不容易掌握(特别是我),所以我一直只会在C++Builder里编程使用FireBird(因为FireBird源于Borland的InterBase,VCL库自带了InterBase的组件),直到有一天我发现了IBPP…
IBPP是一个FireBird/Interbase数据库API的C++包装,使用起来也比较简单,只要把IBPP源码目录里的core/all_in_one.cpp
加入工程,在代码中包含头文件ibpp.h
,最后根据操作系统预定义一个IBPP_WINDOWS
或IBPP_UNIX
的宏即可。
另外,当然还要安装FireBird客户端,如果只是学习,我们可以下载嵌入式版本。IBPP首先要找到FireBird的动态库,在Windows下, IBPP在下面的路径中查找:
- 在程序目录下查找fbembed.dll
- 在程序目录下查找fbclient.dll
- 依据DefaultInstance注册表键值查找fbclient.dll
- 在系统定义位置查找fbclient.dll
- 在系统定义位置查找gds32.dll
FireBird主页:http://www.ibphoenix.com
IBPP主页:http://www.ibpp.org
关于FireBird的中文教程我推荐姚启红编著的《Borland InterBase7.0 应用开发指南》(网上一找一大堆)。
基本应用
1 |
|
要让程序正确执行,就得保证程序能找到FireBird的动态链接库。对于嵌入式版本来说,下载后把压缩包中的fbembed.dll, firebird.conf,firebird.msg,ib_util.dll以及intl文件夹解压到你的程序目录中就可以运行了。对于服务器版,只要安装客户端并把fbclient.dll放到程序目录里就行(当然权限也要有啦)。
上例中使用IBPP的步骤是:
- 用工厂函数
IBPP::DatabaseFactory
生成IBPP::Database
实例,然后调用它的Connect()
成员变量连接数据库。 - 如果要建立数据库的话,使用
Database::Create(int dialect)
。其中dialect一般取值为3,它的含义如下:
值 含义 1 兼容InterBase 5.5及更早版本 2 1和3的过渡版本 3 InterBase 6.0及以后版本,可以使用分隔符,精确数字和时间格式
- 使用工厂函数
IBPP::TransactionFactory
生成IBPP::Transaction
实例,然后用它的Start()
开始事务,最后用Commit()
来提交事务或Rollback()
撤销事务。 - 使用工厂函数
IBPP::StatementFactory
生成IBPP::Statement
实例,然后用它的Execute()
来执行SQL命令。 - 值得注意的是,IBPP中的Database,Transaction,Statement等由工厂函数返回的数据都是智能指针类型,它们能够在退出有效域 时自动执行一些保证完整性的操作。(比如我们使用
tr->Start()
后即便不调用tr->Commit()
,在超出tr变量作用域后系统 也会自动调用Commit
的)
操作Blob型字段
1 |
|
本例连接例一建立的数据库,然后新建一个名为BlobTable
的表,里面只有ID
和RES
字段,而且还为ID
字段建立了一个生成器和触发器,这样就可以 让FireBird自动为ID
赋值了,具体内容可以看FireBird教程。与例一不同的是这里使用了IBPP::Statement
的 ExecuteImmediate()
方法,它立即执行其中的SQL语句,而Execute()
则有一个先准备、再执行的过程,对于只执行一次的SQL, 可以使用ExecuteImmediate()
,如果执行次数较多,则建议使用Execute()
。
RES
字段是一个Blob
型字段,从本例可以看出给Blob
字段赋值的方法是:
- 用
IBPP::Statement
的Prepare()
方法准备SQL插入语句,其中的Blob字段使用问号?
代替。 - 用工厂函数
IBPP::BlobFactory
生成一个IBPP::Blob
实例,然后分别调用它的Create()
,Write()
和Close()
输入数据,最后用IBPP::Statement
的Set()
方法写入。 - 所有数据准备就绪后,执行
IBPP::Statement的Execute()
方法。
如果只想往Blob中存放文本数据,也可以直接用IBPP::Statement
的Set()
方法写入std::string
类型。
从Blob
字段取值的方法正好相反:
- 用
IBPP::Statement
的Execute()
方法或ExecuteImmediate()
方法执行SELECT
语句。 - 使用
IBPP::Statement
的Fetch()
方法提取出当前行的数据。 - 使用
IBPP::Statement
的Get()
方法取出指定列的数据,如果是Blob
类型,则使用IBPP::Blob
实例作为输入。 - 最后分别调用
IBPP::Blob
的Open()
,Read()
和Close()
方法取出数据(IBPP::Blob
也是一个智能指针类型,所以上例中没有显式地使用Close()
关闭)。