BDB C# API初探
Net framework源代码开放算是微软在开源社区开天辟地了,C#作为其主要载体,承载着微软无限希望。这万里长征的第一步,却引起了开源社区的不少涟漪。作为开源社区首屈一指的数据库,BDB借着东风,乘胜追击,推出了其C# API。在此,笔者抛砖引玉,简述C# API如何使用。
1. 概述
BDB C# API建立在BDB C API的基础上,通过上层C#的接口,调用BDB内核。BDB C# API基于.Net Framework 2.0及以上版本,可运行于32位和64位Windows平台,实例开发环境为Microsoft Visual Studio 2005及以上版本。除了特别说明,下文中提到的编译或运行操作均在Microsoft Visual Studio2005中进行。
BDB C# API打包在BDB源代码里(最新代码可从http://www.oracle.com/technology/software/products/berkeley-db/index.html下载)。在BDB的代码中,BDB C# API的代码主要分布于以下目录:
l <db-4.8.24>\csharp:C# API源代码;
l <db-4.8.24>\libdb_csharp:db.i和db_csharp_wrap.c,C# API和C API方法之间的映射;
l <db-4.8.24>\test\scr037:C# API的测试代码;
l <db-4.8.24>\examples_csharp:使用C# API的实例。
通过编译BDB C# API,在<db-4.8.24>\build_windows\AnyCPU\{release, debug}将得到相应的C#库。
BDB C# API支持绝大多数BDB的功能。此外,BDB C#API接口清晰明了,并提供了C#用户专用的参考的使用手册,源代码,测试及多种实例。因此,使用BDB C# API,可以轻松地实现一个功能完备的数据库应用。
2. 编译
编译BDB C# API本身需要BDB C的动态库。在BDB的源代码中,C# API的解决方案已包含了BDB C工程,因此,编译该解决方案,无须另外编译和指定BDB C动态库。

该解决方案文件包含10个工程,其工程名,内容和相对主目录db\的工程文件路径分别是:
|
工程名 |
内容 |
工程文件路径 |
|
db |
C API |
build_windows\db.vcproj |
|
db_csharp |
SWIG生成的封装文件 |
build_windows\db_csharp.vcproj |
|
db_dotnet |
C# API |
csharp\db_dotnet.csproj |
|
DotNetTest |
C# API测试 |
test\scr037\DotNetTest.csproj |
|
ex_access |
B树存取实例 |
examples_csharp\ex_access\ex_access.csproj |
|
ex_btrec |
使用记录号的b树的实例 |
examples_csharp\ex_btrec\ex_btrec.csproj |
|
ex_env |
环境操作实例 |
examples_csharp\ex_env\ex_env.csproj |
|
ex_repquote |
简单的集群实例 |
examples_csharp\ex_repquote\ex_repquote.csproj |
|
ex_sequence |
序列操作实例 |
examples_csharp\ex_sequence\ex_sequence.csproj |
|
ex_txn |
多线程事务实例 |
examples_csharp\ex_txn\ex_txn.csproj |
上述工程可以在单个工程中编译,亦可在整个BDB C# API的解决方案中编译。
(1) 编译解决方案
BDB C# API解决方案已配置好所有BDB C#动态库所需的库及环境。因此,在配置管理器中选择平台(win32或者x64)和编译模式(debug或者release)后,编译该解决方案,便可生成相应的BDB C动态库,C#动态库以及所有实例的可执行文件。如图2和图3所示,进入配置管理器,选择编译配置、平台及工程项。


(2) 编译单个工程
单独编译表格1中的任一工程,打开其工程文件,编译前,应先编译其依赖项。上述10个工程的工程依赖关系,产生的主要对象及其路径如表格2所示:
|
工程名 |
工程依赖 |
产生对象 |
|
Db |
无 |
build_windows\AnyCPU\{debug, release} \{libdb48.dll, libdb48d.dll}, build_windows\ AnyCPU {debug, release } \{libdb48.lib, libdb48d.lib} |
|
db_csharp |
db |
build_windows\AnyCPU\{debug, release} \{ libdb_csharp48.dll, libdb_csharp48d.dll }, build_windows\AnyCPU\{debug, release } \{ libdb_csharp48.lib, libdb_csharp48d.lib } |
|
db_dotnet |
db, db_csharp |
build_windows\AnyCPU\{debug, release } \ libdb_dotnet48.dll |
|
DotNetTest |
db, db_csharp, db_dotnet |
test\scr037\bin\{debug, release}\DotNetTest.dll |
|
ex_access |
db, db_csharp, db_dotnet |
build_windows\AnyCPU\{debug, release} \ex_access.exe |
|
ex_btrec |
db, db_csharp, db_dotnet |
build_windows\AnyCPU\{debug, release} \ex_btrec.exe |
|
ex_env |
db, db_csharp, db_dotnet |
build_windows\AnyCPU\{debug, release} \ex_env.exe |
|
ex_repquote |
db, db_csharp, db_dotnet |
build_windows\AnyCPU\{debug, release}\ex_repquote.exe |
|
ex_sequence
|
db, db_csharp, db_dotnet |
build_windows\AnyCPU\{debug, release} \ex_sequence.exe |
|
ex_txn
|
db, db_csharp, db_dotnet |
build_windows\AnyCPU\{debug, release} \ex_txn.exe |
3. 运行C# API的单元测试
C# API单元测试基于NUnit框架。NUnit是一个开源的面向所有.Net语言的单元测试框架,提供可视化界面和命令行的支持,可在http://www.nunit.org/index.php下载最新版本。
安装完NUnit后,编译DotNetTest测试工程,在<db-4.8.24>\test\scr037\bin\Debug\得到DotNetTest.dll。在NUnit中运行该测试类库前,需要确定libdb48.dll,libdb_csharp48.dll,libdb_dotnet48.dll都在环境变量或者当前目录下。在NUnit中打开生成的DotNetTest.dll,运行该工程,可得到测试结果。
4. 运行示例程序
BDB C# API解决方案提供了6个实例,它们分别是ex_access,ex_btrec,ex_env,ex_repquote,ex_sequence,ex_txn。在解决方案中编译和运行实例工程,在Visual Studio设置该实例工程为启动工程,若依赖的动态链接库已编译,则编译和运行该实例即可。例如,运行ex_txn,编译C#库得到libdb48.dll,libdb_csharp48.dll,libdb_dotnet48.dll,打开ex_txn工程文件,如图4,编译该工程,运行结果如图5所示。


5. 基于BDB C# API的开发
使用BDB C# API进行基于数据库应用程序的开发,需要libdb48.dll,libdb_csharp48.dll和libdb_dotnet48.dll三个动态链接库。首先,在开发的工程中添加libdb_dotnet48.dll的引用,由于libdb_dotnet48.dll需要调用本地代码得到的libdb48d.dll和libdb_csharp48.dll。因此,libdb48d.dll,libdb_csharp48d.dll应放在本工程路径或者环境变量中,以便运行时加载。开发过程中,在代码中添加BDB C# API的命名空间,即“using BerkeleyDB”,便可使用BDB C# API。本文在此举一例子,打开数据库并插入一条Hello World的记录。代码如下:
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using BerkeleyDB;
class Program {
public static void Main(string[] args) {
BTreeDatabaseConfig btreeDBConfig = new BTreeDatabaseConfig();
btreeDBConfig.Creation = CreatePolicy.ALWAYS;
btreeDBConfig.PageSize = 512;
using (BTreeDatabase btreeDB = BTreeDatabase.Open(
"bdb.db", btreeDBConfig)) {
btreeDB.Put(new DatabaseEntry(BitConverter.GetBytes((int)1)),
new DatabaseEntry(ASCIIEncoding.ASCII.GetBytes("Hello World!")));
KeyValuePair pair = btreeDB.Get(new DatabaseEntry(BitConverter.GetBytes((int)1)));
System.Console.WriteLine(ASCIIEncoding.ASCII.GetString(pair.Value.Data));
}
}
}
运行结果显示如下:
BDB是成熟高效的嵌入式引擎,个人认为它提供的C# API在小到手机等消费终端,大至企业级应用都可以使用上BDB这个成熟高效的数据库引擎。更多的信息请参考
http://www.oracle.com/technology/documentation/berkeley-db/db/programmer_reference/csharp.html,欢迎垂询。
berkeleyDB有没有提供这样一种功能:譬如说在数据库环境下创建了一个数据库,能不能配置这个数据库使得数据库有最大文件存储上限,等到达这个上限时,数据库会重新创建一个新的文件进行写记录,如此反复。
请教几个berkeleyDB的问题
1 bdb的高速缓存区 如何设置 在64位的服务器上面 内存64G 未设置的情况下 可以使用到多少 还有就是 高速缓存区里的数据多久消失 我如何管理 可以预热吗。
2 我在写BDB的时候出现过数据库文件损坏 这个可以如何预防 或者补救。
3 BDB的日志文件如何管理。
4 备份是怎么操作的。
@乌鸦精
1. 高速缓存的大小可用{DB, DB_ENV}->set_cachesize设置。在高速缓存中,页被替换的时间跟你的应用数据的访问频率有关。你可根据自身的访问特点,进行预热。
2. 数据库文件损坏后,如果有日志和事务,可以恢复,如果没有日志和事务,可DB_DUMP出来重新装载到一个新的数据库文件中。
3. 你需要如何管理日志文件?请详细说明。
4. 备份分为冷备份和热备份。冷备份是将数据库关闭,将所有文件拷贝到另外一个磁盘空间。热备份是在数据库打开时,进行实时备份,可用db_hotbackup完成,具体可参考http://download.oracle.com/docs/cd/E17076_01/html/api_reference/C/db_hotbackup.html。
BerkeleyDB.PageNotFoundException 中第一次偶然出现的“libdb_dotnet48.dll”类型的异常
这主要是什么造成的了
DB_PAGE_NOTFOUND: Requested page not found
我存储的数据是数组对象 通过Exists判断是存在值的 Get取值的时候 在异常捕获的是上面的错误
如果出现这种错误可以如何处理 我试图删除该键值的数据 或者 写入都报错
还有一个问题就是 我在写入 几百万数据时 采用的是同个对象
也就是说 在开始写入第一条数据打开一个连接 以后都通过该对象写入 直到几百万数据全部写入才关闭。
谢谢版主
@乌鸦精
你好,根据你的描述,你的数据库可能已经损坏。可试图用db_dump导出所有有效数据,并用db_load重载导出的有效数据至一个新的数据文件。
版主你好:
数据库损坏我做了处理机制 我现在还在测试阶段 数据库损坏的频率好像还是蛮高的 几天就会有一次 因为我处理的数据 是批量的 所以采用的数据库连接对象是公用的 打个一个连接 这个连接也许会持续一个小时 读取或者写入数据大概有几百万 同时最大开启48个连接 会不会因为是这个原因造成数据库损坏的了
还有就是写入报错 才try 中都无法捕获异常 在调试模式下也是 在写入数据的时候 应该是数据库损坏造成的
提示的小窗口的内容是
this application has requested the runtime to terminnate it an unusual way please contact the application’s support team for more information
@傅翠云
db.vcproj and db_csharp.vcproj被忽略,不仅仅是4.8.30,5.1.19同样如此,造成了在vs下面利用debug模式调试excs_access的时候,会出一个exception:{“The type initializer for ‘BerkeleyDB.Internal.libdb_csharpPINVOKE’ threw an exception.”},
stack as below:
at BerkeleyDB.Internal.libdb_csharpPINVOKE.new_DB(HandleRef jarg1, UInt32 jarg2)
at BerkeleyDB.Internal.DB..ctor(DB_ENV env, UInt32 flags) in C:\belcon\program\db-5.1.19\lang\csharp\src\Internal\DB.cs:line 109
at BerkeleyDB.BaseDatabase..ctor(DatabaseEnvironment envp, UInt32 flags) in C:\belcon\program\db-5.1.19\lang\csharp\src\BaseDatabase.cs:line 41
at BerkeleyDB.Database..ctor(DatabaseEnvironment env, UInt32 flags) in C:\belcon\program\db-5.1.19\lang\csharp\src\Database.cs:line 29
at BerkeleyDB.BTreeDatabase..ctor(DatabaseEnvironment env, UInt32 flags) in C:\belcon\program\db-5.1.19\lang\csharp\src\BTreeDatabase.cs:line 30
at BerkeleyDB.BTreeDatabase.Open(String Filename, String DatabaseName, BTreeDatabaseConfig cfg, Transaction txn) in C:\belcon\program\db-5.1.19\lang\csharp\src\BTreeDatabase.cs:line 228
at BerkeleyDB.BTreeDatabase.Open(String Filename, BTreeDatabaseConfig cfg) in C:\belcon\program\db-5.1.19\lang\csharp\src\BTreeDatabase.cs:line 97
at excs_access.Program.Main(String[] args) in C:\belcon\program\db-5.1.19\examples\csharp\excs_access\excs_access.cs:line 94
我猜想应该是这两个projects没有被编译的原因,不知道有什么办法可以解决这个问题。
如果单独执行excs_access.exe则没有问题
你好,如果有两个project没有编译,请打开build_windows/BDB_dotNet.sln,进行编译。