BerkeleyDB-JE 使用BaseAPI(五)
    本篇开始介绍游标(Cursors)的应用,主要介绍打开关闭游标以及使用游标来定位记录。
在JE中你可以使用游标来遍历记录,还可以使用游标来增删改记录。同时游标还是唯一一种可以用于访问重复记录集中记录的机制。
一.打开和关闭游标
你可以使用Database.openCursor()方法来打开一个游标,使用Cursor.close()方法来关闭它。需要注意的是关闭游标的顺序,你必须先关闭游标,再关闭Database,最后关闭Environment。
Environment myDbEnvironment = null;
Database myDatabase = null;
Cursor myCursor = null;
try {
    ...
    myCursor = myDatabase.openCursor(null, null);
} catch (DatabaseException dbe) {
  
} finally {
    try {
        if (myCursor != null) {
            myCursor.close();
        }
        if (myDatabase != null) {
            myDatabase.close();
        }
        if (myDbEnvironment != null) {
            myDbEnvironment.close();
        }
    } catch(DatabaseException dbe) {
        System.err.println("Error in close: " + dbe.toString());
    }
}
二.获取记录
游标提供了很多API用于检索记录:
- Cursor.getNext()
 移动游标到下一个记录所在的位置。- Cursor.getPrev()
 移动游标到前一个记录所在的位置。
以上两个API非常简单。- Cursor.getSearchKey()
 这个方法允许你传入一个key值,游标会移动到该传入key值对应的记录所在的位置。- Cursor.getSearchKeyRange()
 这个方法允许你传入一个key值,游标会移动到大于等于该传入key值对应的记录所在的位置。- Cursor.getSearchBoth()
 这个方法允许你传入key值和value值(即一个记录),游标会移动到等于该传入记录的所在的位置。- Cursor.getSearchBothRange()
 这个方法允许你传入key值和value值(即一个记录),游标会移动到键相等并且值会大于等于该传入记录值的记录所在的位置。
这上面的4个API是用来查找记录的,下面用例子解释下,比如我们的数据库中有这样的记录:
| Key | Value | 
| a | v | 
| b | v | 
| b | vv | 
| b | vvv | 
| d | v | 
| d | vvv | 
| Method | Key | Value | Found | 
| getSearchKey | a |  | a/v | 
| getSearchKeyRange | b |  | b/v | 
| getSearchKeyRange | c |  | d/v | 
| getSearchBoth | b | vv | b/vv | 
| getSearchBothRange | d | vv | d/vvv | 
- Cursor.getNextNoDup()
 用于在重复记录集中,游标移动到下一个key值不同的记录- Cursor.getPrevNoDup()
 用于在重复记录集中,游标移动到上一个key值不同的记录- Cursor.getNextDup()
 用于在重复记录集中,游标移动到下一个key值相同的记录- Cursor.getPrevDup()
 用于在重复记录集中,游标移动到上一个key值相同的记录- Cursor.count()
 计算当前重复记录集中的记录个数。
最后这几个API是用于重复记录集的,我们继续用之前的那个数据来演示下,假设当前的游标位于b/vv
| Method | Found | 
| getNextNoDup | d/v | 
| getPrevNoDup | a/v | 
| getNextDup | b/vvv | 
| getPrevDup | b/v | 
| getPrevDup | 3 | 
下面演示下API的例子,先从最简单的getNext开始。
Cursor cursor = null;
try {
    ...
    DatabaseEntry foundKey = new DatabaseEntry();
    DatabaseEntry foundData = new DatabaseEntry();
    cursor = myDatabase.openCursor(null, null);
    while (cursor.getNext(foundKey, foundData, LockMode.DEFAULT) == 
        OperationStatus.SUCCESS) {
        String theKey = new String(foundKey.getData(), "UTF-8");
        String theData = new String(foundData.getData(), "UTF-8");
        System.out.println("Key | Data : " +  theKey + " | " + 
                           theData + "");
    }
} catch (Exception e) {
} finally {
   cursor.close();
}
getPrev是类似的,然后我们演示下查找的API
String searchKey = "Alaska";
String searchData = "Fa";
Cursor cursor = null;
try {
    ...
    cursor = myDatabase.openCursor(null, null);
    DatabaseEntry theKey = 
         new DatabaseEntry(searchKey.getBytes("UTF-8"));
    DatabaseEntry theData = 
         new DatabaseEntry(searchData.getBytes("UTF-8"));
    cursor = myDatabase.openCursor(null, null);
    OperationStatus retVal = cursor.getSearchBothRange(theKey, theData, 
                                                       LockMode.DEFAULT);
    if (retVal == OperationStatus.NOTFOUND) {
        System.out.println(searchKey