Berkeley DB Java Edition

时间:2025-03-22 13:34:09

一、 简介

       Berkeley DB Java Edition (JE)是一个完全用JAVA写的,它适合于管理海量的,简单的数据。

l 能够高效率的处理1到1百万条记录,制约JE数据库的往往是硬件系统,而不是JE本身。

l 多线程支持,JE使用超时的方式来处理线程间的死琐问题。

l Database都采用简单的key/value对应的形式。

l 事务支持。

l 允许创建二级库。这样我们就可以方便的使用一级key,二级key来访问我们的数据。

l 支持RAM缓冲,这样就能减少频繁的IO操作。

l 支持日志。

l 数据备份和恢复。

l 游标支持。

二、 获取JE

JE下载地址:

/technology/software/products/berkeley-db/je/

解开包后 把JE_HOME/lib/je- .jar 中的jar文件添加到你的环境变量中就可以使用je了。

相关帮助文档可以参考 JE_HOME/docs/

源代码见JE_HOME/src/*.*

三、 JE常见的异常

DatabaseNotFoundException 当没有找到指定的数据库的时候会返回这个异常

DeadlockException 线程间死锁异常

RunRecoveryException 回收异常,当发生此异常的时候,你必须得重新打开环境变量。

四、 关于日志文件必须了解的六项

JE的日志文件跟其他的数据库的日志文件不太一样,跟C版的DBD也是有区别的

l JE的日志文件只能APPEND,第一个日志文件名是 ,当他增长到一定大小的时候(默认是10M),开始写第二个日志文件,已此类推。

l 跟C版本有所不同,JE的数据日志和事务日志是放在一起的,而不是分开放的。

l JE cleaner负责清扫没用到的磁盘空间,删除后,或者更新后新的记录会追加进来,而原有的记录空间就不在使用了,cleaner负责清理不用的空间。

l 清理并不是立即进行的,当你关闭你的数据库环境后,通过调用一个cleaner方法来清理。

l 清理也不是只动执行的,需要你自己手动调用cleaner 方法来定时清理的。

l 日志文件的删除仅发生在检查点之后。cleaner准备出哪些log 文件需要被删除,当检查点过后,删掉一些不在被使用的文件。每写20M的日志文件就执行一次检查点,默认下。

五、 创建数据库环境

JE要求在任何DATABASE操作前,要先打开数据库环境,就像我们要使用数据库的话必须得先建立连接一样。你可以通过数据库环境来创建和打开database,或者更改database名称和删除database.

可以通过Environments对象来打开环境,打开环境的时候设置的目录必须是已经存在的目录,否则会出错误。默认情况下,如果指定的database不存在则不会自动创建一个新的detabase,但可以通过设置setAllowCreate来改变这一情况。

1. 打开database环境

示例:

package ;

import ;

import ;

import ;

import ;

...

Environment myDbEnvironment = null;

try {

    EnvironmentConfig envConfig = new EnvironmentConfig();

    (true);//如果不存在则创建一个

    myDbEnvironment = new Environment(new File("/export/dbEnv"), envConfig);

} catch (DatabaseException dbe) {

    // 错误处理

}

2. 关闭database环境

可以通过()这个方法来关闭database环境,当你完成数据库操作后一定要关闭数据库环境。

示例:

import ;

import ;

...

try {

    if (myDbEnvironment != null) {

        ();

    }

} catch (DatabaseException dbe) {

    // Exception handling goes here

}

3. 清理日志

通常在关闭数据库连接的时候,有必要清理下日志,用以释放更多的磁盘空间。我们可以在前执行下()来达到此目的。

示例:

import ;

import ;

...

try {

    if (myDbEnvironment != null) {

        (); // 在关闭环境前清理下日志

        ();

    }

} catch (DatabaseException dbe) {

    // Exception handling goes here

}

4. Database环境的配置

可以通过EnvironmentConfig这个对象来配置database环境。如果想得到当前环境的配置信息则可以通过()方法得到当前环境的配置信息。

也可以使用EnvironmentMutableConfig来配置环境,其实 EnvironmentConfig是EnvironmentMutableConfig的子类,所以EnvironmentMutableConfig能够使用的设置,EnvironmentConfig也同样能够使用。

如果你要获取当前环境的使用情况,那么你可以通过使用().来监视RAM cache命中率。EnvironmentStats可以由()方法获取。

EnvironmentConfig常见方法介绍

l () ;

如果设置了true则表示当数据库环境不存在时候重新创建一个数据库环境,默认为false.

l ()

以只读方式打开,默认为false.

l ()

事务支持,如果为true,则表示当前环境支持事务处理,默认为false,不支持事务处理。

EnvironmentMutableConfig的介绍

l setCachePercent()

设置当前环境能够使用的RAM占整个JVM内存的百分比。

l setCacheSize()

设置当前环境能够使用的最大RAM。单位BYTE

l setTxnNoSync()

当提交事务的时候是否把缓存中的内容同步到磁盘中去。

true 表示不同步,也就是说不写磁盘

l setTxnWriteNoSync()

当提交事务的时候,是否把缓冲的log写到磁盘上

true 表示不同步,也就是说不写磁盘

示例一:

package ;

import ;

import ;

import ;

import ;

...

Environment myDatabaseEnvironment = null;

try {

    EnvironmentConfig envConfig = new EnvironmentConfig();

    //当环境不存在的时候自动创建环境

       (true);

       //设置支持事务

       (true);

    myDatabaseEnvironment =

        new Environment(new File("/export/dbEnv"), envConfig);

} catch (DatabaseException dbe) {

   (());

   (1);

}

示例二:

package ;

import ;

import ;

import ;

import ;

...

try {

    Environment myEnv = new Environment(new File("/export/dbEnv"), null);

    EnvironmentMutableConfig envMutableConfig =

        new EnvironmentMutableConfig();

    (true);

    (envMutableConfig);

} catch (DatabaseException dbe) {

    // Exception handling goes here

}

示例三:

import ;

...

//没有命中的CACHE

long cacheMisses = (null).getNCacheMiss();

...

5. Database操作

在BDB中,数据是以key/value方式成队出现的。

打开database

可以通过()方法打开一个database,在调用这个方法的时候必须指定database的名称。和databaseConfig() (注:数据库设置)

示例:

package ;

import ;

import ;

import ;

import ;

import ;

import ;

...

Environment myDbEnvironment = null;

Database myDatabase = null;

...

try {

    // 打开一个环境,如果不存在则创建一个

    EnvironmentConfig envConfig = new EnvironmentConfig();

    (true);

    myDbEnvironment = new Environment(new File("/export/dbEnv"), envConfig);

    // 打开一个数据库,如果数据库不存在则创建一个

    DatabaseConfig dbConfig = new DatabaseConfig();

(true);

    myDatabase = (null,

"sampleDatabase", dbConfig); //打开一个数据库,数据库名为

                                   //sampleDatabase,数据库的配置为dbConfig

} catch (DatabaseException dbe) {

    // 错误处理

}

关闭database

通过调用()方法来关闭数据库,但要注意,在关闭数据库前必须得先把游标先关闭。

使用示例:

import ;

import ;

import ;

...

try {

        if (myDatabase != null) {

            ();

        }

        if (myDbEnvironment != null) {

            ();

        }

} catch (DatabaseException dbe) {

    // 错误处理

}

设置数据库属性

其实设置数据库属性跟设置环境属性差不多,JE中通过DatabaseConfig对象来设置数据库属性。你能够设置的数据库属性如下。

l ()

如果是true的话,则当不存在此数据库的时候创建一个。

l ()

设置用于Btree比较的比较器,通常是用来排序

l ()

设置用来比较一个key有两个不同值的时候的大小比较器。

l ()

设置一个key是否允许存储多个值,true代表允许,默认false.

l ()

以独占的方式打开,也就是说同一个时间只能有一实例打开这个database。

l ()

以只读方式打开database,默认是false.

l ()

如果设置为true,则支持事务处理,默认是false,不支持事务。

使用示例:

package ;

import ;

import ;

import ;

...

// Environment open omitted for brevity

...

Database myDatabase = null;

try {

    DatabaseConfig dbConfig = new DatabaseConfig();

    (true);

    (true);

    myDatabase =

        (null,

                             "sampleDatabase",

                             dbConfig);

} catch (DatabaseException dbe) {

    // Exception handling goes here.

}

一些用来管理的方法

l ()

取得数据库的名称

如:String dbName = ();

l ()

取得包含这个database的环境信息

如:Environment theEnv = ();

l ()

预先加载指定bytes的数据到RAM中。

如:(1048576l); // 1024*1024

l ()

返回当前环境下的数据库列表

如:

import ;

List myDbNames = ();

for(int i=0; i < (); i++) {

    ("Database Name: " + (String)(i));

}

l ()

删除当前环境中指定的数据库。

如:

String dbName = ();

();

(null, dbName);

l ()

给当前环境下的数据库改名

如:

String oldName = ();

String newName = new String(oldName + ".new", "UTF-8");

();

(null, oldName, newName);

l ()

清空database内的所有数据,返回清空了多少条记录。

如:

Int numDiscarded= (null,

(),true);

("一共删除了 " + numDiscarded +" 条记录 从数据库 " + ());

6. Database 记录

JE的记录包含两部分,key键值和value数据值,这两个值都是通过DatabaseEntry对象封装起来,所以说如果要使用记录,则你必须创建两个DatabaseEntry对象,一个是用来做为key,另外一个是做为value.

DatabaseEntry能够支持任何的能够转换为bytes数组形式的基本数据。包括所有的JAVA基本类型和可序列化的对象.

使用记录

示例一:把字符串转换DatabaseEntry

package ;

import ;

...

String aKey = "key";

String aData = "data";

try {

//设置key/value,注意DatabaseEntry内使用的是bytes数组

DatabaseEntry theKey=new DatabaseEntry(("UTF-8"));

DatabaseEntry theData=new DatabaseEntry(("UTF-8"));

} catch (Exception e) {

    // 错误处理

}

示例二:把DatabaseEntry里的数据转换成字符串

byte[] myKey = ();

byte[] myData = ();

String key = new String(myKey, "UTF-8");

String data = new String(myData, "UTF-8");

读和写database 记录

读和写database记录的时候大体是基本一样的,唯一有区别的是每个key写是否允许写多条记录,默认情况下是不支持多条记录的。

a) 你可以使用如下方法向database 里添加记录

l ()

向database中添加一条记录。如果你的database不支持一个key对应多个data或当前database中已经存在该key了,则使用此方法将使用新的值覆盖旧的值。

l ()

向database中添加新值但如果原先已经有了该key,则不覆盖。不管database是否允许支持多重记录(一个key对应多个value),只要存在该key就不允许添加,并且返回信息。

l ()

想database中添加一条记录,如果database中已经存在了相同的 key和value则返回 .

使用示例:

package ;

import ;

import ;

...

String aKey = "myFirstKey";

String aData = "myFirstData";

try {

    DatabaseEntry theKey = new DatabaseEntry(("UTF-8"));

    DatabaseEntry theData = new DatabaseEntry(("UTF-8"));

    (null, theKey, theData);

} catch (Exception e) {

    // Exception handling goes here

}

b) 你可以使用如下方法从database 里读取记录

1. ()

基本的读记录的方法,通过key的方式来匹配,如果没有改记录则返回。

l ()

通过key和value来同时匹配,同样如果没有记录匹配key和value则会返回

使用示例:

package ;

import ;

import ;

import ;

import ;

...

String aKey = "myFirstKey";

try {

    DatabaseEntry theKey = new DatabaseEntry(("UTF-8"));

    DatabaseEntry theData = new DatabaseEntry();

if ((null, theKey, theData, ) ==

        ) {

        byte[] retData = ();

        String foundData = new String(retData, "UTF-8");

        ("For key: '" + aKey + "' found data: '" +

                            foundData + "'.");

    } else {

        ("No record found for key '" + aKey + "'.");

    }

} catch (Exception e) {

    // Exception handling goes here

}

c) 删除记录

可以使用()这个方法来删除记录。如果你的database支持多重记录,则当前key下的所有记录都会被删除,如果只想删除多重记录中的一条则可以使用游标来删除。

当然你也可以使用()这个方法来清空database 中的所有记录。

使用示例:

package ;

import ;

import ;

...

try {

    String aKey = "myFirstKey";

    DatabaseEntry theKey = new DatabaseEntry(("UTF-8"));

    (null, theKey);

} catch (Exception e) {

}

d) 提交事务

当你对database进行了写操作的时候,你的修改不一定马上就能生效,有的时候他仅仅是缓存在RAM中,如果想让你的修改立即生效,则可以使用()方法来把数据同步到磁盘中去。

e) 不同类型的数据的处理

1. 你可以使用DatabaseEntry来绑定基本的JAVA数据类型,主要有String、Character、Boolean、Byte、Short、Integer、Long、Float、Double.

使用示例一:

package ;

import ;

import ;

import ;

...

try {

    String aKey = "myLong";

    DatabaseEntry theKey = new

    DatabaseEntry(("UTF-8"));   

    Long myLong = new Long(123456789l);

DatabaseEntry theData = new DatabaseEntry();

EntryBinding myBinding =

    ();

    (myLong, theData);

    (null, theKey, theData);

} catch (Exception e) {

    // Exception handling goes here

}

使用示例二:

package ;

import ;

import ;

import ;

import ;

import ;

import ;

...

Database myDatabase = null;

try {

       String aKey = "myLong";

       DatabaseEntry theKey = new

       DatabaseEntry(("UTF-8"));

DatabaseEntry theData = new DatabaseEntry();

EntryBinding myBinding =       

       ();

       OperationStatus retVal = (null, theKey, theData,

       );

       String retKey = null;

       if (retVal == ) {

    Long theLong = (Long) (theData);

           retKey = new String((), "UTF-8");

           ("For key: '" + retKey + "' found Long: '" +

                        theLong + "'.");

       } else {

           ("No record found for key '" + retKey + "'.");

       }

} catch (Exception e) {

       // Exception handling goes here

}

2. 可序列化的对象的绑定

1. 首先你需要创建一个可序列化对象

2. 打开或创建你的database,你需要两个,一个用来存储你的数据,另外一个用来存储类信息。

3. 实例化catalog类,这个时候你可以使用,来存储你的类信息。

4. 通过来绑定数据和类。

5. 绑定并存储数据。

示例:

l 创建一个可序列化的对象

package ;

import ;

public class MyData implements Serializable {

    private long longData;

    private double doubleData;

    private String description;

    MyData() {

        longData = 0;

        doubleData = 0.0;

        description = null;

    }

    public void setLong(long data) {

        longData = data;

    }

    public void setDouble(double data) {

        doubleData = data;

    }

    public void setDescription(String data) {

        description = data;

    }

    public long getLong() {

        return longData;

    }

    public double getDouble() {

        return doubleData;

    }

    public String getDescription() {

        return description;

    }

}

l 存储数据

package ;

import ;

import ;

import ;

import ;

import ;

import ;

...

String aKey = "myData";

MyData data2Store = new MyData();

(123456789l);

(1234.9876543);

("A test instance of this class");

try {

    DatabaseConfig myDbConfig = new DatabaseConfig();

    (true);

    (true);

    Database myDatabase = (null, "myDb", myDbConfig);

    (false);

//打开用来存储类信息的库

    Database myClassDb = (null, "classDb", myDbConfig);

    // 3)创建catalog

    StoredClassCatalog classCatalog = new StoredClassCatalog(myClassDb);

  // 4)绑定数据和类

    EntryBinding dataBinding = new SerialBinding(classCatalog,

                                                 );

    DatabaseEntry theKey = new DatabaseEntry(("UTF-8"));

  // 向DatabaseEntry里写数据

    DatabaseEntry theData = new DatabaseEntry();

    (data2Store, theData);

    (null, theKey, theData);

} catch (Exception e) {

    // 错误处理

}

l 读数据

package ;

import ;

import ;

import ;

import ;

import ;

import ;

import ;

...

// The key data.

String aKey = "myData";

try {

    DatabaseConfig myDbConfig = new DatabaseConfig();

    (false);

    Database myDatabase = (null, "myDb", myDbConfig);

       //用来存储类信息的库

Database myClassDb = (null, "classDb", myDbConfig);

// 实例化catalog

    StoredClassCatalog classCatalog = new StoredClassCatalog(myClassDb);

// 创建绑定对象

    EntryBinding dataBinding = new SerialBinding(classCatalog,

                                                 );

    DatabaseEntry theKey = new DatabaseEntry(("UTF-8"));

    DatabaseEntry theData = new DatabaseEntry();

    (null, theKey, theData, );

    // Recreate the MyData object from the retrieved DatabaseEntry using

    // 根据存储的类信息还原数据

MyData retrievedData=(MyData)(theData);

} catch (Exception e) {

    // Exception handling goes here

}

3. 自定义对象的绑定

使用tuple binding 来绑定自定义数据的步骤

①. 实例化你要存储的对象

②. 通过 class来创建一个tuple binding。

③. 创建一个database,跟序列化的对象不同,你只需要创建一个。

④. 通过继承第二步的类来创建一个entry binding 对象。

⑤. 存储和使用数据

使用示例:

l 创建要存储的对象

package ;

public class MyData2 {

    private long longData;

    private Double doubleData;

    private String description;

    public MyData2() {

        longData = 0;

        doubleData = new Double(0.0);

        description = "";

    }

    public void setLong(long data) {

        longData = data;

    }

    public void setDouble(Double data) {

        doubleData = data;

    }

    public void setString(String data) {

        description = data;

    }

    public long getLong() {

        return longData;

    }

    public Double getDouble() {

        return doubleData;

    }

    public String getString() {

        return description;

    }

}

l 创建一个TupleBinding对象

package ;

import ;

import ;

import ;

public class MyTupleBinding extends TupleBinding {

    // 把对象转换成TupleOutput

    public void objectToEntry(Object object, TupleOutput to) {

        MyData2 myData = (MyData2)object;

(().doubleValue());

        (());

        (());

    }

   //把TupleInput转换为对象

    public Object entryToObject(TupleInput ti) {

Double theDouble = new Double(());

        long theLong = ();

        String theString = ();

        MyData2 myData = new MyData2();

        (theDouble);

        (theLong);

        (theString);

        return myData;

    }

}

l  读和写数据

package ;

import ;

import ;

...

TupleBinding keyBinding = new MyTupleBinding();

MyData2 theKeyData = new MyData2();

(123456789l);

(new Double(12345.6789));

("My key data");

DatabaseEntry myDate = new DatabaseEntry();

try {

    // 把theKeyData 存储到DatabaseEntry里

    (theKeyData, myDate);

    ...

    // Database 进行了一些读和写操作

    ...

    // Retrieve the key data

    theKeyData = (MyData2) (myDate);

} catch (Exception e) {

    // 错误处理

}

f) 使用比较器

JE是使用BTrees来组织结构的,这意味着当对database的读和写需要涉及BTrees间的节点比较。这些比较在key间是经常的发生的。如果你的database支持多重记录,那么也会存在data间的比较。

默认的情况JE的比较器是按照字节的方式来进行比较的,这通常情况下能处理大多数的情况。但有的时候确实需要自定义比较器用于特殊的通途,比如说按照key来排序。

l 创建自己的比较器

其实很简单,只要你重写Comparator class中的比较方法(compare)就可以了,通过()会传递给你两个byte 数组形式的值,如果你知道结构,则可以根据你自己定义的方法来进行比较

示例:

package ;

import ;

public class MyDataComparator implements Comparator {

    public MyDataComparator() {}

    public int compare(Object d1, Object d2) {

        byte[] b1 = (byte[])d1;

        byte[] b2 = (byte[])d2;

        String s1 = new String(b1, "UTF-8");

        String s2 = new String(b2, "UTF-8");

return (s2);

    }

}

l 让database使用你自定义的比较器

如果你想改变database中基本的排序方式,你只能重新创建database并重新导入数据。

①. ()

用于在database里两个key的比较

②. ()

如果为true则代表让database使用 ()设置的比较器来代替默认的比较器。

③. ()

用于database可以使用多重记录的时候的data的 比较。

④. ()

如果为true则代表让database使用 DatabaseConfig. setDuplicateComparator()设置 的比 较器来代替默认的比较器。

使用示例:

package ;

import ;

import ;

import ;

import ;   

...

try {

    DatabaseConfig myDbConfig = new DatabaseConfig();

    (true);

// 设置要使用的比较器

    ();

    // 使用自己定义的比较器

    (true);

    Database myDatabase = (null, "myDb", myDbConfig);

} catch (DatabaseException dbe) {

    // Exception handling goes here

}

六、 游标的使用

游标提供了遍历你database中记录的一种机制,使用游标你可以获取,添加,和删除你的记录。如果你的database支持多重记录,则可以通过游标访问同一个key下的每一个记录。

l 打开和关闭游标

要想使用游标则你必须通过()方法来打开一个游标,你可以通过CursorConfig来配置你的游标。

可以通过()方法来关闭游标。请注意在关闭database和环境前一定要关闭游标,否则会带来错误。

打开游标示例:

package ;

import ;

import ;

import ;

import ;

import ;

import ;

...

Environment myDbEnvironment = null;

Database myDatabase = null;

Cursor myCursor = null;

try {

    myDbEnvironment = new Environment(new File("/export/dbEnv"), null);

    myDatabase = (null, "myDB", null);

    myCursor = (null, null);

} catch (DatabaseException dbe) {

    // Exception handling goes here ...

}

关闭游标示例:

package ;

import ;

import ;

import ;

...

try {

    ...

} catch ... {

} finally {

    try {

        if (myCursor != null) {

            ();

        }

        if (myDatabase != null) {

            ();

        }

        if (myDbEnvironment != null) {

            ();

        }

    } catch(DatabaseException dbe) {

        ("Error in close: " + ());

    }

}

l 通过游标来获取记录

可以通过游标的()方法来遍历记录,()表示游标指针向下移动一条记录。同样的()表示游标指针向上移动一条记录。

使用示例一:

package ;

import ;

import ;

import ;

import ;

import ;

import ;

...

Cursor cursor = null;

try {

    cursor = (null, null);

    DatabaseEntry foundKey = new DatabaseEntry();

    DatabaseEntry foundData = new DatabaseEntry();

    // 通过方法来遍历记录

while ((foundKey, foundData, ) ==

        ) {

String keyString = new String((), "UTF-8");

        String dataString = new String((), "UTF-8");

        ("Key | Data : " + keyString + " | " +

                       dataString + "");

    }

} catch (DatabaseException de) {

    ("Error accessing database." + de);

} finally {

    // 使用后必须关闭游标

    ();

}

使用示例二:

package ;

import ;

import ;

import ;

import ;

import ;

import ;

...

Cursor cursor = null;

try {

    ...

    // Open the cursor.

    cursor = (null, null);

    DatabaseEntry foundKey = new DatabaseEntry();

    DatabaseEntry foundData = new DatabaseEntry();

    // 使用方法来遍历游标获取数据

   while ((foundKey, foundData, )

       == ) {

        String theKey = new String((), "UTF-8");

        String theData = new String((), "UTF-8");

        ("Key | Data : " + theKey + " | " + theData + "");

    }

} catch (DatabaseException de) {

    ("Error accessing database." + de);

} finally {

    // 使用后必须关闭游标

    ();

}

l 搜索数据

你可以通过游标方式搜索你的database记录,你也可以通过一个key来搜索你的记录,同样的你也可以通过key和value组合在一起来搜索记录。如果查询失败,则游标会返回。

游标支持都检索方法如下:

1) ()

通过key的方式检索,使用后游标指针将移动到跟当前key匹配的第一项。

2) ()

把游标移动到大于或等于查询的key的第一个匹配key,大小比较是通过你设置的比较器来完成的,如果没有设置则使用默认的比较器。

3) ()

通过key和value方式检索,然后把游标指针移动到与查询匹配的第一项。

4) ()

把游标移动到所有的匹配key和大于或等于指定的data的第一项。

比如说database存在如下的key/value记录,,大小比较是通过你设置的比较器来完成的,如果没有设置则使用默认的比较器。

假设你的database存在如下的记录。

               Alabama/Athens
               Alabama/Florence
               Alaska/Anchorage
               Alaska/Fairbanks
                Arizona/Avondale
               Arizona/Florence

然后查询

查询的key

查询的data

游标指向

Alaska

Fa

Alaska/Fairbanks

Arizona

Fl

Arizona/Florence

Alaska

An

Alaska/Anchorage

使用示例:

package ;

import ;

import ;

import ;

import ;

import ;

import ;

...

String searchKey = "Alaska";

String searchData = "Fa";

Cursor cursor = null;

try {

    ...

    cursor = (null, null);

    DatabaseEntry theKey =

         new DatabaseEntry(("UTF-8"));

    DatabaseEntry theData =

         new DatabaseEntry(("UTF-8"));

    cursor = (null, null);

OperationStatus retVal = (theKey,

theData, );

    if (retVal == ) {

        (searchKey + "/" + searchData +

                           " not matched in database " +

                           ());

    } else {

        String foundKey = new String((), "UTF-8");

        String foundData = new String((), "UTF-8");

        ("Found record " + foundKey + "/" + foundData +

                           "for search key/data: " + searchKey +

                           "/" + searchData);

    }

} catch (Exception e) {

    // Exception handling goes here

} finally {

   ();

}

l 使用游标来定位多重记录

如果你的库支持多重记录,你可以使用游标来遍历一个key下的多个data.

1) (), ()

获取上一条记录或下一条记录

2) ()

用语定位到满足指定data的第一条记录。

3) (), ()

跳到上一个key的最后一个data或下一个key的第一个data,忽略 当前key多重记录的存在。

4) (), ()

在当前key中把指针移动到前一个data或后一个data.

5) ()

获取当前key下的data总数。

使用示例:

package ;

import ;

import ;

import ;

import ;

import ;

import ;

...

Cursor cursor = null;

try {

    ...

    // Create DatabaseEntry objects

    // searchKey is some String.

    DatabaseEntry theKey = new DatabaseEntry(("UTF-8"));

    DatabaseEntry theData = new DatabaseEntry();

    cursor = (null, null);

OperationStatus retVal = (theKey,

theData, );

    // 如果count超过一个,则遍历

    if (() > 1) {

        while (retVal == ) {

            String keyString = new String((), "UTF-8");

            String dataString = new String((), "UTF-8");

            ("Key | Data : " + keyString + " | " +

                               dataString + "");

            retVal = (theKey, theData, );

        }

    }

} catch (Exception e) {

    // Exception handling goes here

} finally {

   // Make sure to close the cursor

   ();

}

l 通过游标来添加数据

你可以通过游标来向database里添加数据

你可以使用如下方法来向database里添加数据

1) ()

如果database不存在key,则添加,如果database存在key但允许多重记录,则可以通过比较器在适当的位置插入数据,如果key已存在且不支持多重记录,则替换原有的数据。

2) ()

如果存在相同的key和data则返回.

如果不存在key则添加数据。

3) ()

如果存在相同的key在database里则返,

如果不存在key则添加数据。

package ;

import ;

import ;

import ;

import ;

...

String key1str = "My first string";

String data1str = "My first data";

String key2str = "My second string";

String data2str = "My second data";

String data3str = "My third data";

Cursor cursor = null;

try {

    ...

    DatabaseEntry key1 = new DatabaseEntry(("UTF-8"));

    DatabaseEntry data1 = new DatabaseEntry(("UTF-8"));

    DatabaseEntry key2 = new DatabaseEntry(("UTF-8"));

    DatabaseEntry data2 = new DatabaseEntry(("UTF-8"));

    DatabaseEntry data3 = new DatabaseEntry(("UTF-8"));

    cursor = (null, null);

OperationStatus retVal = (key1, data1); // 添加成功

    retVal = (key2, data2); // 添加成功

    retVal = (key2, data3); // 如果允许多重记录则添加成功                                                                                      //否则添加失败

} catch (Exception e) {

    // Exception handling goes here

} finally {

   // Make sure to close the cursor

   ();

}

l 使用游标来删除记录

你可以通过调用().方法来删除当前游标所指向的记录。删除后如果没有移动过指针这个时候调用()还是可以得到当前值的,但移动以后就不可以了。如果没有重设指针,对同一个位置多次调用删除方法,会返回状态。

使用示例:

package ;

import ;

import ;

import ;

import ;

import ;

...

Cursor cursor = null;

try {

    ...

    DatabaseEntry theKey = new DatabaseEntry(("UTF-8"));

    DatabaseEntry theData = new DatabaseEntry();

    cursor = (null, null);

    OperationStatus retVal = (theKey, theData,                                        );

    //如果date不是多重记录.

    if (() == 1) {

            ("Deleting " +

                               new String((), "UTF-8") +

                               "|" +

                               new String((), "UTF-8"));

            ();//删除当前记录

    }

} catch (Exception e) {

    // Exception handling goes here

} finally {

   // Make sure to close the cursor

   ();

}

l 修改当前游标所在位置的值

可以通过()方法来修改,这个方法只有一个参数就是将要修改的值。这个方法不能用在多重记录。

使用示例:

import ;

import ;

import ;

import ;

import ;

...

Cursor cursor = null;

try {

    ...

    DatabaseEntry theKey = new DatabaseEntry(("UTF-8"));

    DatabaseEntry theData = new DatabaseEntry();

    cursor = (null, null);

    OperationStatus retVal = (theKey, theData,

);

    //将要被替换的值

    String replaceStr = "My replacement string";

    DatabaseEntry replacementData =

        new DatabaseEntry(("UTF-8"));

    (replacementData);//把当前位置用新值替换

} catch (Exception e) {

    // Exception handling goes here

} finally {

   // Make sure to close the cursor

   ();

}