/*
* BDB je操作核心类
*/
package com.ego.data.db.bdb;
import com.ego.file.Directory;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.serial.SerialBinding;
import com.sleepycat.bind.serial.StoredClassCatalog;
import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.je.Cursor;
import com.sleepycat.je.CursorConfig;
import com.sleepycat.je.Database;
import com.sleepycat.je.DatabaseConfig;
import com.sleepycat.je.DatabaseEntry;
import com.sleepycat.je.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.LockMode;
import com.sleepycat.je.OperationStatus;
import com.sleepycat.je.Transaction;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* BDB je操作核心类。
* <p>功能:
* <br>打开(创建数据库)、打开(创建表)、输入数据、获取数据。
* <br>注意;数据表的默认属性是表不存在自动创建,表打开方式可读可写,不支持多重记录,不支持事务。默认不支持多重记录,如果打
* 开表写数据时是用多重记录配置打开,那么在读时也应用多重记录配置打开,否则出错。默认情况下,不支持相同记录(忽略相同记录添加),
* 相同记录即键和值都与既存记录相等。
* <p>步骤:
* <br>1、创建BDB数据库对象
* <p> BDB db=new BDB(new File("D:/gradel"));
* <br>2、打开数据库
* <p> db.openDatabase();或db.openDatabase(new File("D:/grade2"))
* <br>3、打开数据表
* <p> db.openTable("v");
* <br>4、添加数据
* <p> db.addInt("w", 1);或db.add("w",1);db.add("w",1)这种形式最好不要用,因为取值的时候是按照值类型方法取得的。
* <br>添加值应与取得值一致,否则会出错。
* <br>5、获取数据
* <p> db.getInt("w", 1);
* <br>6、修改数据
* <p> db.updateInt("w", 5);
* <p><b>如果要存储序列化对象,还要在存储前调用setStoreSerialObject(String classInfoStoreTableName)指定存储类信息的表名。
* <br>7、关闭数据库
* <p> db.close(); 记得关闭很重要。一是释放资源;二是在写入或修改数据库后必须关闭才能写入到实际数据库中。如果
* 用到resultset还必须关闭resultset.close();否则出错
*/
public class BDB {
private File dbPath=null;
private EnvironmentConfig dbConfig=null;
private Environment db=null;
private DatabaseConfig tableConfig=null;
private Database table=null;
private boolean dbAutoCreate=true;
private boolean dbReadOnly=false;
private boolean dbIsTransactional=true;
private boolean tableAutoCreate=true;
private boolean tableReadOnly=false;
private boolean tableIsTransactional=true;
private String charsetName="utf-8";
private String classInfoStoreTableName=null;
private Database classInfoStoreTable=null;
private boolean isSortedDuplicate=false;
private Transaction transaction=null;
/**
* 构建bdb数据库对象实例,但数据库尚未初始化,及未建立与数据库的连接
* @param dbPath数据库的路径
*/
public BDB(File dbPath){
this.dbPath=dbPath;
if(!this.dbPath.exists())this.dbPath.mkdirs();
}
/**
* 构建bdb数据库对象实例,但数据库尚未初始化,及未建立与数据库的连接
* @param dbPath数据库的路径
* @param autoCreate如果数据库不存在是否创建
*/
public BDB(File dbPath,boolean autoCreate){
this.dbPath=dbPath;
if(!this.dbPath.exists())this.dbPath.mkdirs();
}
//打开数据库操作
/**
* 数据库初始化,即创建与指定数据库的连接
* @return 数据库对象,即Environment对象
*/
public Environment openDatabase(){
this.dbConfig=new EnvironmentConfig().setAllowCreate(dbAutoCreate).setReadOnly(dbReadOnly).setTransactional(dbIsTransactional);
return this.db=new Environment(dbPath, dbConfig);
}
/**
* 数据库初始化,即创建与指定数据库的连接
* @param autoCreate数据库不存在是否自动创建,true自动创建
* @param readOnly打开数据库是否只读
* @param isTransactional数据库是否支持事务处理
* @return 数据库对象,即Environment对象
*/
public Environment openDatabase(boolean autoCreate,boolean readOnly,boolean isTransactional){
this.dbConfig=new EnvironmentConfig().setAllowCreate(autoCreate).setReadOnly(readOnly).setTransactional(isTransactional);
return this.db=new Environment(dbPath, dbConfig);
}
/**
* 数据库初始化,即创建与指定数据库的连接
* @param dbConfig数据库配置对象EnvironmentConfig
* @return 数据库对象,即Environment对象
*/
public Environment openDatabase(EnvironmentConfig dbConfig){
this.dbConfig=dbConfig;
return this.db=new Environment(dbPath, dbConfig);
}
/**
* 打开数据库,以给定的参数数据库地址打开数据库。以后的操作对象将是此时打开的数据库
* @param databasePath数据库地址
* @return 数据库对象,即Environment对象
*/
public Environment openDatabase(File databasePath){
this.dbConfig=dbConfig;
return this.db=new Environment(databasePath, dbConfig);
}
/**
* 打开数据库,以给定的参数数据库地址和数据库属性配置对象打开数据库。以后的操作对象将是此时打开的数据库
* @param databasePath数据库地址
* @param dbCofig
* @return 数据库对象,即Environment对象
*/
public Environment openDatabase(File databasePath,EnvironmentConfig dbCofig){
this.dbConfig=dbConfig;
return this.db=new Environment(databasePath,dbCofig);
}
//打开数据表操作
/**
* 打开指定名称的表,默认属性为不存在则创建,不为只读,支持事务处理
* @param tableName表明
* @return 数据表Database
* @throws Exception如果尚未建立数据库连接抛出
*/
public Database openTable(String tableName) throws Exception{
return this.opentTable(tableName,true,false, false,null,null);
}
/**
* 打开指定名称的表,
* @param tableName表名
* @param tableAutoCreate不存在是否创建
* @param tableReadOnly是否以只读打开
* @param isSortedDuplicate是否支持多重记录
* @return Database数据表
* @throws Exception如果尚未建立数据库连接抛出
*/
public Database openTable(String tableName,boolean tableAutoCreate,
boolean tableReadOnly,boolean isSortedDuplicate) throws Exception{
return this.opentTable(tableName,tableAutoCreate,tableReadOnly, isSortedDuplicate,null,null);
}
/**
* 打开指定名称的表,
* @param tableName表名
* @param tableConfig表的配置
* @return Database
* @throws Exception如果尚未建立数据库连接抛出
*/
public Database openTable(String tableName,DatabaseConfig tableConfig) throws Exception{
return this.opentTable(tableName,true,false, false,tableConfig,null);
}
/**
* 打开指定名称的表,
* @param tableName表名
* @param tableConfig表的配置
* @param transaction事务处理对象
* @return Database
* @throws Exception如果尚未建立数据库连接抛出
*/
public Database opentTable(String tableName,DatabaseConfig tableConfig,
Transaction transaction) throws Exception{
this.transaction=transaction;
return this.opentTable(tableName,true,false, false,tableConfig,transaction);
}
private Database opentTable(String tableName,boolean tableAutoCreate,boolean tableReadOnly,
boolean isSortedDuplicate,DatabaseConfig tableConfig,Transaction transaction) throws Exception{
if(this.db==null)throw new Exception("hava not connect the database");
this.tableConfig=tableConfig!=null?tableConfig:new DatabaseConfig().setAllowCreate(tableAutoCreate)
.setReadOnly(tableReadOnly).setSortedDuplicates(isSortedDuplicate).setTransactional(dbIsTransactional);
this.table=db.openDatabase(transaction, tableName, this.tableConfig);
this.isSortedDuplicate=this.table.getConfig().getSortedDuplicates();
return this.table;
}
/**
* 如果要存储序列化对象类型数据,还需要指定一个存储类信息数据表的名字
* @param classTableName 要保存类信息的表名字
*/
public void setStoreSerialObject(String classInfoStoreTableName) throws Exception{
if(this.db==null)throw new Exception("hava not connect the database");
if(classInfoStoreTableName==null)throw new Exception("classInfoStoreTableNam can't be null");
this.classInfoStoreTableName=classInfoStoreTableName;
this.classInfoStoreTable=db.openDatabase(null,classInfoStoreTableName,new DatabaseConfig().setAllowCreate(dbAutoCreate).setSortedDuplicates(false));
}
/**
* 返回。。。。此功能暂不支持
* @deprecated
* @return 。。。
*/
public String getInfoStoreTableName(){
return this.classInfoStoreTableName;
}
//数据表操作开始
/**
* 获取指定关键词的字符串形式值,如果表支持多重记录,则如果键对应多个值,则返回第一条记录
* @param key要获取的键
* @return 对应键的值,如果对应的没有值则返回null,如果设置了多重记录就返回第一条
* @throws Exception
*/
public String getString(String key) throws Exception {
checkDbAndTable();
byte[] theKey = key.getBytes(this.charsetName);
DatabaseEntry queryKey = new DatabaseEntry(theKey);
DatabaseEntry storeValue = new DatabaseEntry();
OperationStatus status = table.get(this.transaction, queryKey,storeValue, LockMode.DEFAULT);
if (status == OperationStatus.SUCCESS) {
return new String(storeValue.getData(), this.charsetName);
}
return null;
}
/**
* 获取指定关键词的证型数值形式值。如果表支持多重记录,则如果键对应多个值,则返回第一条记录
* @param key
* @return int,如果没有找到对应的值,默认为0
* @throws Exception
*/
public int getInt(String key) throws Exception {
int ret = 0;
try {
ret =getNumeric(key,ret);
} catch (Exception ex) {
ret = 0;
}
return ret;
}
/**
* 获取指定关键词的证长型数值形式值。如果表支持多重记录,则如果键对应多个值,则返回第一条记录
* @param key
* @return long,如果没有找到对应的值,默认为0
* @throws Exception 如果没有找到对应键的值则抛出错误
*/
public long getLong(String key) throws Exception {
long ret=0;
try {
ret =getNumeric(key,ret);
} catch (Exception ex) {
ret = 0;
}
return ret;
}
/**
* 获取指定关键词的双精度型数值形式值
* @param key
* @return double,如果没有找到对应的值,默认为0
* @throws Exception
*/
public double getDouble(String key) throws Exception {
double ret = 0;
try {
ret =getNumeric(key,ret);
} catch (Exception ex) {
ret = 0;
}
return ret;
}
/**
* 获取指定关键词的单精度型数值形式值
* @param key
* @return float,如果没有找到对应的值,默认为0
* @throws Exception
*/
public float getFloat(String key) throws Exception {
float ret = 0;
try {
ret =getNumeric(key,ret);
} catch (Exception ex) {
ret = 0;
}
return ret;
}
//获取数值型数据
private <E > E getNumeric(String key,E type) throws Exception{
checkDbAndTable();
byte[] theKey = key.getBytes(this.charsetName);
DatabaseEntry queryKey = new DatabaseEntry(theKey);
DatabaseEntry storeValue = new DatabaseEntry();
EntryBinding myBinding =TupleBinding.getPrimitiveBinding(type.getClass());
OperationStatus retVal = table.get(this.transaction, queryKey,storeValue, LockMode.DEFAULT);
E ret;
if (retVal == OperationStatus.SUCCESS) {
ret = (E) myBinding.entryToObject(storeValue);
}else{
throw new Exception("not found");
}
return ret;
}
/**
* 从BDB数据表中获取记录
* @param <T>泛型参数
* @param key要获得的键
* @param cl获取对象的class对象
* @return如果找到对应值返回值,如没有返回null
* @throws Exception 如果数据库没有连接或存储数据或存储类信息的表没有打开抛出异常
*/
public <T> T getSerialObject(String key,T serialObject) throws Exception {
checkDbAndTable();
if(this.classInfoStoreTable==null) throw new Exception("the table that store class information dos't exsit");
StoredClassCatalog classCatalog = new StoredClassCatalog(this.classInfoStoreTable);
// Create the binding创建绑定
EntryBinding dataBinding = new SerialBinding(classCatalog,serialObject.getClass());
byte[] theKey = key.getBytes(this.charsetName);
DatabaseEntry queryKey = new DatabaseEntry(theKey);
// Create the DatabaseEntry for the data. Use the EntryBinding object用入口绑定对象为数据创建数据库入口
// that was just created to populate the DatabaseEntry
DatabaseEntry value = new DatabaseEntry();
OperationStatus retVal = table.get(this.transaction, queryKey,value, LockMode.DEFAULT);
if (retVal == OperationStatus.SUCCESS) {
T retrievedData = (T) dataBinding.entryToObject(value);
return retrievedData;
}
return null;
}
/**
* 获取自定义记录绑定对象数据
* @param <E>返回的类型
* @param key获取的键
* @param tupleBinding自定义记录绑定器
* @return 存在返回成功,反之false
* @throws Exception
*/
public <E> E getTupleObject(String key,TupleBinding tupleBinding) throws Exception {
checkDbAndTable();
byte[] theKey = key.getBytes(this.charsetName);
DatabaseEntry queryKey = new DatabaseEntry(theKey);
// Create the DatabaseEntry for the data. Use the EntryBinding object用入口绑定对象为数据创建数据库入口
// that was just created to populate the DatabaseEntry
DatabaseEntry value = new DatabaseEntry();
OperationStatus retVal = table.get(this.transaction, queryKey,value, LockMode.DEFAULT);
if (retVal == OperationStatus.SUCCESS) {
E retrievedData = (E) tupleBinding.entryToObject(value);
return retrievedData;
}
return null;
}
/**
* 获取表中的所有记录保存在resultset中
* @return ResultSet结果记录集
* @throws Exception
*/
public ResultSet getAll() throws Exception{
checkDbAndTable();
Cursor cursor=this.table.openCursor(transaction, CursorConfig.DEFAULT);
return new ResultSet(cursor, isSortedDuplicate, classInfoStoreTable,this.charsetName) ;
}
/**
* 获取表中的指定记录保存在resultset中
* @param key
* @return
* @throws Exception
*/
public ResultSet get(String key) throws Exception{
checkDbAndTable();
Cursor cursor=this.table.openCursor(transaction, CursorConfig.DEFAULT);
ResultSet resultSet=new ResultSet(cursor, isSortedDuplicate, classInfoStoreTable,this.charsetName,key) ;
return resultSet;
}
/**
* 向数据表中插入以字符串形式指定的数据
* @param key键
* @param 要插入的字符串值
* @return OperationStatus,如果表支持多重记录,且键已经存在,添加一个新纪录;如果表不支持多重记录,且键已经存在,会返回已经存在
* @throws Exception 如果没有连接数据库或没有打开表抛出错误
*/
public OperationStatus addString(String key, String value) throws Exception {
return add(key,value);
}
/**
* 向数据表中插入以整型形式指定的数据
* @param key键
* @param 要插入的整型数值
* @return OperationStatus,如果表支持多重记录,且键已经存在,添加一个新纪录;如果表不支持多重记录,且键已经存在,会返回已经存在
* @throws Exception 如果没有连接数据库或没有打开表抛出错误
*/
public OperationStatus addInt(String key, int value) throws Exception {
return add(key,value);
}
/**
* 向数据表中插入以双精度形式指定的数据
* @param key键
* @param 要插入的双精度型数值
* @return OperationStatus,如果表支持多重记录,且键已经存在,添加一个新纪录;如果表不支持多重记录,且键已经存在,会返回已经存在
* @throws Exception 如果没有连接数据库或没有打开表抛出错误
*/
public OperationStatus addDouble(String key, double value) throws Exception {
return add(key,value);
}
/**
* 向数据表中插入以单精度形式指定的数据.
* @param key键
* @param 要插入的单精度型数值
* @return OperationStatus,如果表支持多重记录,且键已经存在,添加一个新纪录;如果表不支持多重记录,且键已经存在,会返回已经存在
* @throws Exception 如果没有连接数据库或没有打开表抛出错误
*/
public OperationStatus addFloat(String key, float value) throws Exception {
return add(key,value);
}
/**
* 添加原始类型数据。如果表支持多重记录,且键已经存在,添加一个新纪录;如果表不支持多重记录,且键已经存在,会返回已经存在
* @param <E>原始类型
* @param key
* @param value
* @return
* @throws Exception
*/
public <E > OperationStatus add(String key,E value) throws Exception{
checkDbAndTable();
byte[] theKey = key.getBytes(this.charsetName);
DatabaseEntry queryKey = new DatabaseEntry(theKey);
DatabaseEntry storeValue = new DatabaseEntry();
EntryBinding myBinding =TupleBinding.getPrimitiveBinding(value.getClass());
myBinding.objectToEntry(value, storeValue);
OperationStatus status;
if(this.isSortedDuplicate){
status = table.put(this.transaction,queryKey, storeValue) ;
}else{
status = table.putNoOverwrite(this.transaction, queryKey, storeValue);
}
return status;
}
/**
* 将序列化对象存入bdb数据表中
* @param key键
* @param obj要存储的序列化对象,这个对象是实现序列化的
* @return OperationStatus,如果表支持多重记录,且键已经存在,添加一个新纪录;如果表不支持多重记录,且键已经存在,会返回已经存在
* @throws Exception 如果数据库没有连接或存储数据或存储类信息的表没有打开抛出异常
*/
public OperationStatus addSerialObject(String key, Object serialValue) throws Exception {
checkDbAndTable();
if(this.classInfoStoreTable==null) throw new Exception("the table that store class information dos't exsit");
StoredClassCatalog classCatalog = new StoredClassCatalog(this.classInfoStoreTable);
// Create the binding创建绑定
EntryBinding dataBinding = new SerialBinding(classCatalog, serialValue.getClass());
byte[] theKey = key.getBytes(this.charsetName);
// Create the DatabaseEntry for the data. Use the EntryBinding object用入口绑定对象为数据创建数据库入口
// that was just created to populate the DatabaseEntry
DatabaseEntry theData = new DatabaseEntry();
dataBinding.objectToEntry(serialValue, theData);
OperationStatus status;
if(this.isSortedDuplicate){
status = table.put(this.transaction,new DatabaseEntry(theKey), theData) ;
}else{
status = table.putNoOverwrite(this.transaction, new DatabaseEntry(theKey), theData);
}
return status;
}
/**
* 将自定义记录对象数据存储打开的表中,无重复添加,即键不能重复
* @param <E>泛型
* @param key存储在表中的键
* @param obj要存储的自定义记录对象
* @param tupleBinding自定义记录绑定
* @return OperationStatus,如果表支持多重记录,且键已经存在,添加一个新纪录;如果表不支持多重记录,且键已经存在,会返回已经存在
* @throws Exception
*/
public <E> OperationStatus addTupleObject(String key,E tupleObj,TupleBinding tupleBinding) throws Exception {
checkDbAndTable();
byte[] theKey = key.getBytes(this.charsetName);
// Create the DatabaseEntry for the data. Use the EntryBinding object用入口绑定对象为数据创建数据库入口
// that was just created to populate the DatabaseEntry
DatabaseEntry theData = new DatabaseEntry();
tupleBinding.objectToEntry(tupleObj, theData);
//将对象数据存储在表中
OperationStatus status;
if(this.isSortedDuplicate){
status = table.put(this.transaction,new DatabaseEntry(theKey), theData) ;
}else{
status = table.putNoOverwrite(this.transaction,new DatabaseEntry(theKey), theData);
}
return status;
}
/**
* 删除指定key的记录。可以使用Database.delete()这个方法来删除记录。如果你的database支持多重记录,
* 则当前key下的所有记录都会被删除,如果只想删除多重记录中的一条则可以使用游标来删除。
* 当然你也可以使用Environment.truncateDatabase()这个方法来清空database 中的所有记录
* @param key要删除的指定关键
* @return 布尔型,删除成功返回true
* @throws Exception
*/
public boolean delete(String key) throws Exception {
checkDbAndTable();
byte[] theKey = key.getBytes(this.charsetName);
OperationStatus status = table.delete(this.transaction, new DatabaseEntry(theKey));
if (status == OperationStatus.SUCCESS) {
return true;
}
return false;
}
/**
* 修改记录,如果不支持多重记录则修改指定记录。如果支持多重记录,则删除指定键的所有记录后添加指定修改的键/值
* @param key
* @param value
* @return
* @throws Exception Exception 如果要修改的记键不存在抛出错误
*/
public OperationStatus updateString(String key,String value) throws Exception{
checkDbAndTable();
return update(key,value);
}
/**
* 修改记录,如果不支持多重记录则修改指定记录。如果支持多重记录,则删除指定键的所有记录后添加指定修改的键/值
* @param key
* @param value
* @return
* @throws Exception Exception 如果要修改的记键不存在抛出错误
*/
public OperationStatus updateInt(String key, int value) throws Exception {
checkDbAndTable();
return update(key,value);
}
/**
* 修改记录,如果不支持多重记录则修改指定记录。如果支持多重记录,则删除指定键的所有记录后添加指定修改的键/值
* @param key
* @param value
* @return
* @throws Exception Exception 如果要修改的记键不存在抛出错误
*/
public OperationStatus updateDouble(String key, double value) throws Exception {
checkDbAndTable();
return update(key,value);
}
/**
* 修改记录,如果不支持多重记录则修改指定记录。如果支持多重记录,则删除指定键的所有记录后添加指定修改的键/值
* @param key
* @param value
* @return
* @throws Exception Exception 如果要修改的记键不存在抛出错误
*/
public OperationStatus updateFloat(String key, float value) throws Exception {
checkDbAndTable();
return update(key,value);
}
/**
* 修改原始类型数据。如果不支持多重记录则修改指定记录。如果支持多重记录,则删除指定键的所有记录后添加指定修改的键/值
* @param <E>修改的原型
* @param key
* @param value修改的类型
* @return
* @throws Exception 如果要修改的记键不存在抛出错误
*/
public <E > OperationStatus update(String key,E value) throws Exception{
checkDbAndTable();
Cursor cursor =this.table.openCursor(transaction, CursorConfig.DEFAULT);
DatabaseEntry queryKey = new DatabaseEntry(key.getBytes(this.charsetName));
DatabaseEntry storeValue = new DatabaseEntry();
OperationStatus retVal = cursor.getSearchKey(queryKey, storeValue, LockMode.DEFAULT);
if(retVal!=OperationStatus.SUCCESS){
cursor.close();
return OperationStatus.NOTFOUND;
}
DatabaseEntry replacementData = new DatabaseEntry();
EntryBinding myBinding =TupleBinding.getPrimitiveBinding(value.getClass());
myBinding.objectToEntry(value, replacementData);
//如果是多重记录,则删除记录再添加
if(this.isSortedDuplicate){
delete(key);
retVal=add(key, value);
}else{
retVal=cursor.putCurrent(replacementData);
}
cursor.close();
return retVal;
}
/**
* 修改记录,如果不支持多重记录则修改指定记录。如果支持多重记录,则删除指定键的所有记录后添加指定修改的键/值
* @param key键
* @param serialValue要存储的序列化对象,这个对象是实现序列化的
* @return
* @throws
*/
public <T> OperationStatus updateSerialObject(String key, Object serialValue,T serialObject) throws Exception {
checkDbAndTable();
if(this.classInfoStoreTable==null) throw new Exception("the table that store class information dos't exsit");
Cursor cursor =this.table.openCursor(transaction, CursorConfig.DEFAULT);
DatabaseEntry queryKey = new DatabaseEntry(key.getBytes(this.charsetName));
DatabaseEntry storeValue = new DatabaseEntry();
OperationStatus retVal = cursor.getSearchKey(queryKey, storeValue, LockMode.DEFAULT);
if(retVal!=OperationStatus.SUCCESS){
cursor.close();
return OperationStatus.NOTFOUND;
}
DatabaseEntry replacementData = new DatabaseEntry();
StoredClassCatalog classCatalog = new StoredClassCatalog(this.classInfoStoreTable);
// Create the binding创建绑定
EntryBinding dataBinding = new SerialBinding(classCatalog, serialObject.getClass());
DatabaseEntry replacementDatat = new DatabaseEntry();
dataBinding.objectToEntry( serialValue, replacementData);
//如果是多重记录,则删除记录再添加
if(this.isSortedDuplicate){
delete(key);
retVal=addSerialObject(key, serialValue);
}else{
retVal=cursor.putCurrent(replacementData);
}
cursor.close();
return retVal;
}
/**
* 修改自定义记录。如果不支持多重记录则修改指定记录。如果支持多重记录,则删除指定键的所有记录后添加指定修改的键/值
* @param <E>自定义对象类型
* @param key要修改的键
* @param tupleValue新对象值
* @param tupleBinding指定的记录绑定对象
* @return
* @throws Exception
*/
public <E> OperationStatus updateTupleObject(String key,E tupleValue,TupleBinding tupleBinding) throws Exception {
checkDbAndTable();
Cursor cursor =this.table.openCursor(transaction, CursorConfig.DEFAULT);
DatabaseEntry queryKey = new DatabaseEntry(key.getBytes(this.charsetName));
DatabaseEntry storeValue = new DatabaseEntry();
OperationStatus retVal = cursor.getSearchKey(queryKey, storeValue, LockMode.DEFAULT);
if(retVal!=OperationStatus.SUCCESS){
cursor.close();
return OperationStatus.NOTFOUND;
}
DatabaseEntry replacementData = new DatabaseEntry();
tupleBinding.objectToEntry( tupleValue, replacementData);
//如果是多重记录,则删除记录再添加
if(this.isSortedDuplicate){
delete(key);
retVal=addTupleObject(key, tupleValue, tupleBinding);
}else{
retVal=cursor.putCurrent(replacementData);
}
cursor.close();
return retVal;
}
//检查数据库或数据表是否存在
private void checkDbAndTable() throws Exception{
if(this.db==null ||this.table==null)throw new Exception("hava not connect the database or do not open the table");
}
/**
* 关闭数据库及表。在修改、写入数据后必须调用此方法,否则数据不能写入物理数据库
*/
public void close(){
if(this.table!=null){
this.tableConfig=null;
this.table.close();
}
if(this.db!=null){
this.dbConfig=null;
this.db.close();
}
}
public static void main(String[] args){
try {
BDB db=new BDB(new Directory("D:/gradel/f", true));
Environment e= db.openDatabase();
db.openTable("b", true, false, true);
db.addString("2013-03-04","2012-02-04");
db.addString("2012-02-12", "hhhhhhhh");
db.addString("2012-03-04", "5555");
db.addString("2012-12-04","dddddddddddd");
db.addString("2013-02-04", "hhhhhhhh");
db.addString("9013-08-04", "5555");
db.addString("a","a1");
db.addString("a", "a2");
db.addString("a", "a3");
db.addString("a","a4");
db.addString("a", "a5");
db.addString("a", "a6");
db.addString("a","a1");
db.addString("a", "a2");
db.addString("a", "a3");
db.addString("a","a4");
db.addString("a", "a5");
db.addString("a", "a6");
db.addString("a","a1yyyyyyyyyyyyyyyyyyyyyyyyy7777");
db.addString("a", "a2");
db.addString("a", "ayyyyyyyyyyy3");
db.addString("a","a4");
db.addString("a", "a577777777777");
db.addString("a6ttt", "a6");
// db.updateInt("o",9);
// db.update("5",4444444);
// db.add("f",7788);
db.close();
BDB dbb=new BDB(new Directory("D:/gradel/f", true));
dbb.openDatabase();
dbb.openTable("b", true, false, true);
ResultSet rs=dbb.get("a");
// ResultSet rs=dbb.getAll();
// System.out.print(rs.first());
while(rs.next()){
System.out.print(rs.getCurrentPostion());
System.out.println(rs.getKey()+"____"
+rs.getString());
}
System.out.println(rs.getRecordCount());
// System.out.println(rs.moveTo(1));
// rs.next();
// rs.moveTo(0); rs.next();
rs.setPageSize(2);
rs.setCurrentPage(1);
// rs.first();;
System.out.println(rs.getCurrentPostion());
System.out.println(rs.getKey()+"____"
+rs.getString());
rs.close();
dbb.close();
} catch (Exception ex) {
Logger.getLogger(BDB.class.getName()).log(Level.SEVERE, null, ex);
}
}
}