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用于检索记录:
[list]
[*]Cursor.getNext()
移动游标到下一个记录所在的位置。
[*]Cursor.getPrev()
移动游标到前一个记录所在的位置。
以上两个API非常简单。
[*]Cursor.getSearchKey()
这个方法允许你传入一个key值,游标会移动到该传入key值对应的记录所在的位置。
[*]Cursor.getSearchKeyRange()
这个方法允许你传入一个key值,游标会移动到大于等于该传入key值对应的记录所在的位置。
[*]Cursor.getSearchBoth()
这个方法允许你传入key值和value值(即一个记录),游标会移动到等于该传入记录的所在的位置。
[*]Cursor.getSearchBothRange()
这个方法允许你传入key值和value值(即一个记录),游标会移动到键相等并且值会大于等于该传入记录值的记录所在的位置。
这上面的4个API是用来查找记录的,下面用例子解释下,比如我们的数据库中有这样的记录:
[table]
|Key|Value|
|a|v|
|b|v|
|b|vv|
|b|vvv|
|d|v|
|d|vvv|
[/table]
[table]
|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|
[/table]
[*]Cursor.getNextNoDup()
用于在重复记录集中,游标移动到下一个key值不同的记录
[*]Cursor.getPrevNoDup()
用于在重复记录集中,游标移动到上一个key值不同的记录
[*]Cursor.getNextDup()
用于在重复记录集中,游标移动到下一个key值相同的记录
[*]Cursor.getPrevDup()
用于在重复记录集中,游标移动到上一个key值相同的记录
[*]Cursor.count()
计算当前重复记录集中的记录个数。
最后这几个API是用于重复记录集的,我们继续用之前的那个数据来演示下,假设当前的游标位于b/vv
[table]
|Method|Found|
|getNextNoDup|d/v|
|getPrevNoDup|a/v|
|getNextDup|b/vvv|
|getPrevDup|b/v|
|getPrevDup|3|
[/table]
[/list]
下面演示下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 + "/" + searchData +
" not matched in database " +
myDatabase.getDatabaseName());
} else {
String foundKey = new String(theKey.getData(), "UTF-8");
String foundData = new String(theData.getData(), "UTF-8");
System.out.println("Found record " + foundKey + "/" + foundData +
"for search key/data: " + searchKey + "/" + searchData);
}
} catch (Exception e) {

} finally {
cursor.close();
}

最后演示下游标操作重复记录集

Cursor cursor = null;
try {
...
DatabaseEntry theKey = new DatabaseEntry(searchKey.getBytes("UTF-8"));
DatabaseEntry theData = new DatabaseEntry();
cursor = myDatabase.openCursor(null, null);

OperationStatus retVal = cursor.getSearchKey(theKey, theData,
LockMode.DEFAULT);

if (cursor.count() > 1) {
while (retVal == OperationStatus.SUCCESS) {
String keyString = new String(theKey.getData(), "UTF-8");
String dataString = new String(theData.getData(), "UTF-8");
System.out.println("Key | Data : " + keyString + " | " +
dataString + "");

retVal = cursor.getNextDup(theKey, theData, LockMode.DEFAULT);
}
}
} catch (Exception e) {
} finally {
cursor.close();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值