体验完XML版的BDB后,得更往前整点了。官方的文档,看得我有些头大,一个上午过去了,自己都绕晕在里面了。还是找本书先看看吧。专门讲Berkeley DB的书还真不多,我就只找到两本:Apress.The.Definitive.Guide.to.Berkeley.DB.XML.Aug.2006,Apress.The.Berkeley.DB.Book.Oct.2007。

大概翻了一下,觉得先读07年那本,顺带可以练练C++,好久没用都生疏了。

1、再说概念

与大多数数据库系统不同,“表”在Berkeley DB中被称为“数据库”,“数据库”被称为数据库环境。

访问API

BDB Java 版提供了三种数据访问存取API。基本的API提供了一个简单的键值对模型来存储和检索数据。直接持久层(Direct Persistence Layer DPL)API 可以通过默认构造方法保存任何一个Java类到数据库,并且提供丰富的数据检索API集合来获取数据。不仅如此,集合API还扩展了众所周知Java集合API,添加了数据持久性和事务支持。

Say Hello To BDB_职场

Berkeley DB Java版是一个与核心版本没有任何关系的完全独立的产品。但Java APIs是非常类似的,都支持通用的Java集合API。 Java应用程序可以使用了Berkeley DB的集合API在核心版和Java版本之间无缝切换。
XML版和核心版用的是同一个的数据库引擎,它提供高性能的事务性数据存储。它们之间的主要区别是XML版还包含一个全面的XML分析器查询优化器。

Berkeley DB Java版就是为了给Java应用程序提供一个快速、可靠的缓存机制而应运而生的。缓存对我来说不陌生,之前在电信行业的时候,接触了不少内存数据库的东东。什么Oracle的TimesTen,韩国的Altibase,还有原来公司自己整的一个MDB。这样看来其实 BDB 也应该归到内存数据库之列,这么一想倒感觉BDB没那么神奇了,顶着个No Sql 的光环,里面还不是那是老生常谈的技术。

2、安装

说了这么多,整点实在的,动手操作吧!

Say Hello To BDB_职场_02

解压吧:tar -zxf db-5.1.25.tar.gz

( ⊙ o ⊙ )啊!报一堆:time stamp 2011-02-01 04:08:47 is xxx s in the future

查看时间,发现虚拟机还漫步在2010,赶紧改过来:date -s "10 Feb 2011 18:03:00"

Say Hello To BDB_DB_03

好,接下来开始编译。

sh ../dist/configure --prefix=/opt/soft/oracle/bdb/install -enable-cxx

这一步居然没报啥错。忐忑不安的开始 make ,又开始了漫长的等待。

。。。。。。。。。

屏幕终于停下来了,睁大眼睛一看,居然又过了。敲入 make install,数秒后安装结束,头一次在Linux装东西这么顺利。

嘿嘿,难道水平见长啦。到安装目录检查一把。

 Say Hello To BDB_Berkeley_04

Say Hello To BDB_休闲_05

Say Hello To BDB_职场_06

Say Hello To BDB_职场_07

貌似都是正常的。

接下来配下环境变量

vi .bashrc

在最后添加一段

# BDB Settings
BDB_HOME=/opt/soft/oracle/bdb/install; export BDB_HOME
PATH=/usr/sbin:$PATH; export PATH
PATH=$BDB_HOME/bin:$PATH; export PATH

LD_LIBRARY_PATH=$BDB_HOME/lib:/lib:/usr/lib; export LD_LIBRARY_PATH

3、Hello World

现在我们就来玩玩在计算机界无人不知无人不晓的“Hello World”之BDB版。

#include <iostream>

#include <db_cxx.h>

using std::cout;
using std::endl;
using std::cerr;

void errCallback (const DbEnv *env, const char *prefix, const char *errMsg)
{
    cout &lt;&lt; prefix &lt;&lt; " " &lt;&lt; errMsg &lt;&lt; endl;
}

int main(int argc, char **argv)
{

    /* 创建数据库句柄 */
    Db db(0, 0);

    try
    {
        db.set_errpfx("hello_world");
        db.set_errcall(errCallback);

/* 使用句柄打开数据库 */

db.open(NULL,
                "./chap4_db",
                NULL,
                DB_BTREE,
                DB_CREATE,
                0644);

/* 创建键和值,并保存到 Dbt 对象 */

        char *first_key = "first_record";
        u_int32_t key_len = (u_int32_t)strlen(first_key);
        char *first_value = "Hello World - Berkeley DB style!!";
        u_int32_t value_len = (u_int32_t)strlen(first_value);

        Dbt key(first_key, key_len + 1 );
        Dbt value(first_value, value_len + 1);

/* 使用 put 方法插入键值对 */

        int ret;
        ret = db.put(0,
                     &key,
                     &value,
                     DB_NOOVERWRITE);

        if (ret == DB_KEYEXIST)
        {
            db.err(ret, "");
        }

/* 读取插入到数据库中的数据 */

        Dbt stored_value;
        ret = db.get(0,
                     &key,
                     &stored_value,
                     0);

/* 利用get_data() 方法取得数据并打印到stdout */
cout &lt;&lt; (char *)stored_value.get_data() &lt;&lt; endl;

        /* 关闭数据库句柄 */

db.close(0);

    }
    catch(DbException &dbex)
    {
        db.err(dbex.get_errno(), "Db exception caught");
    }
}

代码没什么好说的,提一下Dbt类。

Dbt 类
BDB本身并不清楚将要保存到数据库中的是键值对结构。所有的键和值被视为二进制数据块。 Dbt类就是对二进制数据的封装。看看运行效果吧。书上的代码是Scons来编译的。得了,先把Scons装上,不过有RPM包,挺Easy的。

Scons http://www.scons.org/

rpm -ivh scons-2.0.1-1.noarch.rpm

这里源代码需要做一点小的改动,因为我安装数据库的目录跟书上的不同。

MYLIBPATH 的路径要换一下。OK,开编吧,编译结果如下。

Say Hello To BDB_Berkeley_08

很好,跑一次试试。

Say Hello To BDB_DB_09

不容易啊,你终于出来了,Hello World。

再跑一次看看。

Say Hello To BDB_DB_10

提示已经存在,嘿嘿,不错!