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();
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章