`
mengyang
  • 浏览: 266125 次
  • 性别: Icon_minigender_1
  • 来自: 福州
社区版块
存档分类
最新评论

BerkeleyDB-JE 使用BaseAPI(三)

    博客分类:
  • BDB
 
阅读更多
本篇开始介绍BIND APIs
我们已经知道,要想在JE中读写数据,必须借助DatabaseEntry对象,而原始数据和DatabaseEntry对象之间的转换,实际上要做的就是把数据转化为字节数组或者是把字节数组组装成数据。除了String类型和布尔型的数据,要进行这样的转换则必须使用JE中的BIND APIs。
可以使用BIND APIs的数据基本上分为三种:
  • 简单类型的数据
  • 实现了serialization接口的复杂类型数据
  • 没有实现serialization接口的复杂类型数据

以上三种数据使用BIND APIs的方式是各不相同的。
一.简单类型的数据
简单类型的数据包括了:String,Character,Boolean,Byte,Short,Integer,Long,Float,Double。要想把这类型的数据存储到DatabaseEntry,有两个步骤:
1.使用TupleBinding.getPrimitiveBinding返回一个可以转化相应类型的EntryBinding对象。
2.使用得到的EntryBinding对象把数据放到DatabaseEntry中。
下面演示这个过程
try {
    String aKey = "myLong";
    DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));    

    Long myLong = new Long(123456789l);
    DatabaseEntry theData = new DatabaseEntry();
    EntryBinding myBinding = TupleBinding.getPrimitiveBinding(Long.class);
    myBinding.objectToEntry(myLong, theData);

    myDatabase.put(null, theKey, theData);
} catch (Exception e) {
    
}

要想从DatabaseEntry中获得数据也要借助EntryBinding对象
try {
    String aKey = "myLong";
    DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
    
    DatabaseEntry theData = new DatabaseEntry();
    EntryBinding myBinding = TupleBinding.getPrimitiveBinding(Long.class);

    if (myDatabase.get(null, theKey, theData, LockMode.DEFAULT) == OperationStatus.SUCCESS) {
        Long theLong = (Long) myBinding.entryToObject(theData);
        retKey = new String(theKey.getData(), "UTF-8");
        System.out.println("For key: '" + retKey + "' found Long: '" + theLong + "'.");
    } 
} catch (Exception e) {
    
}

二.实现了serialization接口的复杂类型数据
在实际使用中,像上面那个例子中的数据库里的记录-键和值都只是一个简单类型的字段的情况是很少见的。更常见的是我们会使用复杂类型的对象,它里面封装了多个字段。如果这个复杂类型对象实现了serialization接口,我们要把这个数据转入转出字节数组,我们可以使用序列化方法(Java serialization),但是这样不好,最主要的原因是如果这样做你会存储非常多无用的信息到JE中。所以我们要使用BIND APIs执行序列化,并且使用BIND APIs仍然会得到序列化对象的所有好处。
使用BIND APIs执行序列化的步骤如下:
1.首先你要读写的类必须实现serialization接口。
2.打开两个database,一个用于保存要读写的数据,另外一个用于保存数据的类型信息。
3.创建StoredClassCatalog对象,这个对象代表了一个类型目录,它需要传入保存数据的类型信息的数据库。
4.创建EntryBinding对象,它需要传入StoredClassCatalog对象和序列化对象的类信息。
5.使用SerialBinding对象把数据放到DatabaseEntry
下面演示这个过程,首先是你要保存到JE的类
public class MyData implements Serializable {
    private long longData;
    private double doubleData;
    private String description;
    //省略get和set方法...
}

接下去是你要序列化的方法:
String aKey = "myData";
MyData data2Store = new MyData();
data2Store.setLong(123456789l);
data2Store.setDouble(1234.9876543);
data2Store.setDescription("A test instance of this class");
try {
    DatabaseConfig myDbConfig = new DatabaseConfig();
    myDbConfig.setAllowCreate(true);
    Database myDatabase = myDbEnv.openDatabase(null, "myDb", myDbConfig);
    Database myClassDb = myDbEnv.openDatabase(null, "classDb", 
                                              myDbConfig); 

    StoredClassCatalog classCatalog = new StoredClassCatalog(myClassDb);
    EntryBinding dataBinding = new SerialBinding(classCatalog, 
                                                 MyData.class);

    DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
    DatabaseEntry theData = new DatabaseEntry();
    dataBinding.objectToEntry(data2Store, theData);

    myDatabase.put(null, theKey, theData);
} catch (Exception e) {

}

下面演示反序列化
String aKey = "myData";
try {
    DatabaseConfig myDbConfig = new DatabaseConfig();
    myDbConfig.setAllowCreate(false);
    Database myDatabase = myDbEnv.openDatabase(null, "myDb", myDbConfig);
    Database myClassDb = myDbEnv.openDatabase(null, "classDb", 
                                              myDbConfig); 
    StoredClassCatalog classCatalog = new StoredClassCatalog(myClassDb);
    EntryBinding dataBinding = new SerialBinding(classCatalog, 
                                                 MyData.class);
    DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
    DatabaseEntry theData = new DatabaseEntry();
    myDatabase.get(null, theKey, theData, LockMode.DEFAULT);
    MyData retrievedData = (MyData) dataBinding.entryToObject(theData);
 
} catch (Exception e) {

}

三.没有实现serialization接口的复杂类型数据
我们使用自定义的元组绑定(Custom Tuple Bindings)来转换这类型的数据。必须首先说明的是对于任何类型的数据,包括实现了serialization接口类型的数据仍然可以使用这种方法。而且按照官方文档上的说明,是推荐对任何复杂类型数据都使用这种方法的。它有以下的优点:
  • 支持排序,通过序列化得到的字节数组的顺序是没有意义的
  • 压缩数据量,比序列化得到的字节数组大小上小很多
  • 加速原始数据和字节数组的转换过程,比序列化转换来的快
  • 可以使用自定的比较器,使用序列化绑定的方法是无法使用自定义比较器的

使用的步骤有:
1.编写你需要读写到JE的类,它可以不用实现serialization接口
2.使用TupleBinding类新建一个元组绑定器(tuple binding)
3.打开数据(只要一个就好)
4.使用你新建的元组绑定器(tuple binding)创建EntryBinding对象
5.使用EntryBinding对象把数据放到DatabaseEntry
下面给出演示:
首先是要读写到JE的类
public class MyData2 {
    private long longData;
    private double doubleData;
    private String description;
    //省略get和set方法...
}

然后你要必须为这个类创建一个元组绑定器(tuple binding),你必须继承TupleBinding类,然后实现两个抽象方法:TupleBinding.objectToEntry() and TupleBinding.entryToObject()。同时有几点你要注意:
  • 使用objectToEntry()方法转换对象到字节数组。你可以使用TupleOutput转化原始类型的数据。使用的时候要注意对数值型数据的处理,它只能接受原始类型的数据(比如long, double, int...),而不能处理它们的封装类型(比如Long, Double, Integer...)。
  • 你使用objectToEntry()方法转化对象中每个字段的顺序关系到对字节数组的排序,以上面的MyData2类为例,如果转化的顺序是longData,doubleData,description,那么得到的字节数组就会先按顺序的保存这些成员变量,这也意味着你的记录将先按longData的值来排序,而后是doubleData,最后是description。如果你想按doubleData来排序,那你就必须首先转化这个成员变量。
  • 使用entryToObject()方法转换字节数组到对象。你可以使用TupleInput来执行这个转换。
  • 从字节数组中读取成员变量的顺序必须跟你转化成员变量到字节数组的顺序一致。

public class MyTupleBinding extends TupleBinding {
// 转换对象到字节数组
public void objectToEntry(Object object, TupleOutput to) {
MyData2 myData = (MyData2)object;
to.writeDouble(myData.getDouble().doubleValue());
to.writeLong(myData.getLong());
to.writeString(myData.getString());
}
// 转换字节数组为对象
public Object entryToObject(TupleInput ti) {
Double theDouble = new Double(ti.readDouble());
long theLong = ti.readLong();
String theString = ti.readString();
MyData2 myData = new MyData2();
myData.setDouble(theDouble);
myData.setLong(theLong);
myData.setString(theString);
return myData;
}
}

最后你就可以读写数据了
TupleBinding keyBinding = new MyTupleBinding();
MyData2 theKeyData = new MyData2();

theKeyData.setLong(123456789l);
theKeyData.setDouble(new Double(12345.6789));
theKeyData.setString("My key data");
DatabaseEntry myKey = new DatabaseEntry();
try {
// Store theKeyData in the DatabaseEntry
keyBinding.objectToEntry(theKeyData, myKey);
...
// Database put and get activity omitted for clarity
...
// Retrieve the key data
theKeyData = (MyData2) keyBinding.entryToObject(myKey);
} catch (Exception e) {
// Exception handling goes here
}
0
1
分享到:
评论

相关推荐

    BerkeleyDB-JE je-6.0.11

    Oracle BerkeleyDB-JE je-6.0.11

    BerkeleyDB-Core-C-GSG.pdf

    本手册是为初学者及有一定经验的开发者设计的,旨在提供一个全面、系统的指南来帮助读者理解 Berkeley DB 的基本概念、数据库管理、记录操作、游标使用以及二级数据库的实现等方面的知识。此外,手册还详细介绍了...

    Berkeley DB JE-7.0.6

    **Berkeley DB JE 7.0.6:深入理解分布式数据存储** Berkeley DB JE(Java Edition)是Oracle公司提供的一款开源、嵌入式、基于Java的键值对数据库系统。它以其轻量级、高性能和高可用性而受到广泛的青睐,尤其适合...

    Java-Edition-BerkeleyDB-3.1.0.zip_BerkeleyDB

    在Je-3.1.0版本中,BerkeleyDB使用特定的数据库文件格式,这些文件可以在不同平台上进行迁移,确保了跨平台的兼容性。 **7. 性能优化** BerkeleyDB提供了多种性能调优选项,如缓存大小设置、日志文件管理等,...

    BerkeleyDB-Core-Cxx-GSG.rar

    **Berkeley DB (BDB)** 是一款开源的、嵌入式数据库系统,由...通过详读并实践“BerkeleyDB-Core-Cxx-GSG.pdf”中的内容,开发者将能够熟练地在C++项目中集成和使用Berkeley DB,从而实现高效、可靠的数据存储和管理。

    BerkeleyDB-Core-Cxx-GSG.rar_Berkeley DB_berkeley Db cxx

    在C++接口方面,Berkeley DB提供了丰富的类库供开发者使用。例如,`Db`类用于表示数据库对象,`DbEnv`类用于管理数据库环境,而`Dbt`类则用于存储和检索数据库中的数据项。通过这些类,开发者可以方便地进行数据库的...

    db-4.7.25-master_db-4.7.25-master_berkeleydbvxworks_BerkeleyDB_源

    Berkeley DB是一个开源的文件数据库,介于关系数据库与内存数据库之间,使用方式与内存数据库类似,它提供的是一系列直接访问数据库的函数,而不是像关系数据库那样需要网络通讯、SQL解析等步骤,本文件是早期版本

    BerkeleyDB-Core-JAVA-GSG.pdf

    根据提供的文档信息,“BerkeleyDB-Core-JAVA-GSG.pdf”主要介绍了如何在Java环境中使用Berkeley DB。该文档强调了Berkeley DB作为一种文件类型数据库的优势,包括快速的存取速度和方便的操作特性。 #### 二、...

    BerkeleyDB-0.26

    - 在并发处理方面,Sqlite 使用行级锁定,而 BerkeleyDB 使用多版本并发控制,对于高并发环境,BerkeleyDB 可能表现更好。 总的来说,BerkeleyDB 和 Sqlite 都是优秀的嵌入式数据库解决方案,选择哪一个取决于具体...

    BerkeleyDB-0.27

    **BerkeleyDB** 是一款强大的、高度可定制的嵌入式数据库系统,广泛应用于各种软件开发,尤其是在需要高效存储和检索数据的场景中。这款数据库系统由Oracle公司开发,最初在1990年由Sleepycat Software推出,因其...

    Berkeley DB -- Access Method Configuration_iyangjian200599

    (二) Berkeley DB -- Access Method Configuration_iyangjian2005997_新浪博客.mht

    Berkeley DB4.8以上各版本

    3. **空间效率**:Berkeley DB通常关注内存和磁盘空间的使用效率,4.8版本可能进一步降低了存储开销,从而在资源有限的环境中更高效。 4. **错误处理和恢复**:为了提高系统的健壮性,4.8版本可能增强了错误检测和...

    Berkeley DB -- 入门知识和一个小例子_iyangjian2005997_新浪博客.mht

    Berkeley DB -- 入门知识和一个小例子_iyangjian2005997_新浪博客.mht

    BerkeleyDB Manual C/C++

    《BerkeleyDB Manual C/C++》是一份详尽的官方文档,主要针对使用C和C++语言进行数据库操作的开发者。BerkeleyDB是一款轻量级、高性能的关系型数据库管理系统,常用于嵌入式系统和分布式应用程序。这篇手册将深入...

    berkeley db db-6.1.26.tar.gz

    db-6.1.26.tar.gz berkeley db

    Berkeley DB Java Edition (JE)

    Berkeley DB Java Edition (JE) 官方7.5.11下载版本。 相关介绍 https://blog.csdn.net/hadues/article/details/80854288

    BerkeleyDB_java_jar包

    2. **Java API**:一组接口和类,如`Database`、`DatabaseEntry`和`Transaction`,使得开发者可以使用Java代码与BerkeleyDB进行交互。 3. **示例和文档**:可能包含演示如何使用BerkeleyDB Java API的示例代码,以及...

    Berkeley DB C++编程入门教

    标题“Berkeley DB C++编程入门教程”意味着文档旨在引导读者通过C++语言了解和使用Berkeley DB。这种数据库提供了一个简洁的API,使得开发者可以快速地存储和检索数据,无需复杂的数据库配置或管理。 在描述中提到...

    BerkerleyDb-18.1.40.tar.gz

    三、BerkeleyDB在Scrapy-Deltafetch中的应用 Scrapy-Deltafetch是一个基于Scrapy的爬虫框架扩展,用于高效地抓取网站增量更新。BerkeleyDB作为其依赖,主要作用是存储已抓取的数据,以便于后续比较和分析增量更新。...

Global site tag (gtag.js) - Google Analytics