Java嵌入式数据库berkeleyDB(三)
修改了每次存放一个对象,
同时增加了对key的范围搜索和范围删除
参考了同事的部分代码,优化了配置,同时修复了以下问题:
1、取数据没有数据时报nullpoint的错误
2、搜索数据没有关闭transaction的错误
package com.sillycat.plugin.berkeley.impl;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import com.sillycat.core.model.User;
import com.sillycat.plugin.commons.utils.StringUtil;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.serial.SerialBinding;
import com.sleepycat.bind.serial.StoredClassCatalog;
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.DatabaseException;
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;
public class BerkeleyDBServiceImpl {
// 数据库的默认路径
private static final String DB_ENVIRONMENT_ROOT = "D:/dbRoot";
// 数据库环境
private Environment databaseEnv;
// 数据
private static Database cacheDatabase;
// 类
private static Database classBindingDatabase;
// 数据绑定的环境
private EntryBinding dataBinding;
// 数据库路径
private String databasePath;
/**
* 初始化数据参数
*/
public void init() {
try {
EnvironmentConfig config = new EnvironmentConfig();
config.setAllowCreate(true);// 如果不存在则创建一个
config.setReadOnly(false); // 以只读方式打开,默认为false
config.setTransactional(true); // 事务支持,如果为true,则表示当前环境支持事务处理,默认为false,不支持事务处理
databaseEnv = new Environment(new File(this.getDatabasePath()),
config);
DatabaseConfig dbConfig = new DatabaseConfig();
dbConfig.setAllowCreate(true);
dbConfig.setTransactional(true);
// 初始化缓存数据库
cacheDatabase = databaseEnv.openDatabase(null, "cacheDatabase",
dbConfig);
classBindingDatabase = databaseEnv.openDatabase(null,
"classDatabase", dbConfig);
StoredClassCatalog classCatalog = new StoredClassCatalog(
classBindingDatabase);
dataBinding = new SerialBinding(classCatalog, Object.class);
} catch (DatabaseException e) {
e.printStackTrace();
}
}
/**
*
* 关闭database环境
*/
public void destroy() {
try {
if (cacheDatabase != null) {
cacheDatabase.close();
}
if (classBindingDatabase != null) {
classBindingDatabase.close();
}
if (databaseEnv != null) {
databaseEnv.cleanLog(); // 在关闭环境前清理下日志
databaseEnv.close();
}
} catch (DatabaseException e) {
e.printStackTrace();
}
}
/**
* 放入对象
*
* @param key
* @param obj
*/
public void putObject(String key, Object obj) {
DatabaseEntry theKey;
try {
DatabaseEntry theData = new DatabaseEntry();
theKey = new DatabaseEntry(key.getBytes("UTF-8"));
dataBinding.objectToEntry(obj, theData);
cacheDatabase.put(null, theKey, theData);
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
} catch (DatabaseException e) {
e.printStackTrace();
}
}
/**
* 取出对象
*
* @param key
* @return
* @throws DatabaseException
* @throws UnsupportedEncodingException
*/
public Object getObject(String key) {
DatabaseEntry theKey;
Object retData = null;
try {
theKey = new DatabaseEntry(key.getBytes("UTF-8"));
DatabaseEntry theData = new DatabaseEntry();
cacheDatabase.get(null, theKey, theData, LockMode.DEFAULT);
if (theData.getSize() > 0) {
retData = (Object) dataBinding.entryToObject(theData);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (DatabaseException e) {
e.printStackTrace();
}
return retData;
}
/**
* 删除数据
*
* @param key
*/
public void delete(String key) {
DatabaseEntry theKey;
try {
theKey = new DatabaseEntry(key.getBytes("UTF-8"));
cacheDatabase.delete(null, theKey);
// 删除数据
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (DatabaseException e) {
e.printStackTrace();
}
}
/**
*
* 搜索范围内的数据
*
* @param begin
* @param end
* @return
* @throws DatabaseException
* @throws UnsupportedEncodingException
*/
public List searchRange(long begin, long end) {
List list = null;
Cursor cursor = null;
Transaction txn = null;
try {
txn = databaseEnv.beginTransaction(null, null);
CursorConfig config = new CursorConfig();
config.setReadCommitted(true);
cursor = cacheDatabase.openCursor(txn, config);
DatabaseEntry theKey = new DatabaseEntry((begin + "")
.getBytes("UTF-8"));
DatabaseEntry theData = new DatabaseEntry();
OperationStatus retVal = cursor.getSearchKeyRange(theKey, theData,
LockMode.DEFAULT);
// 如果count超过一个,则遍历
if (cursor.count() >= 1) {
list = new ArrayList();
while (retVal == OperationStatus.SUCCESS) {
String keyString = new String(theKey.getData(), "UTF-8");
String dataString = new String(theData.getData(), "UTF-8");
// retVal = cursor.getNextDup(theKey, theData,
// LockMode.DEFAULT);
long timeStamp = Long.parseLong(keyString);
if (timeStamp >= begin && timeStamp < end) {
list.add(dataString);
retVal = cursor.getNext(theKey, theData,
LockMode.DEFAULT);
} else {
break;
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (cursor != null) {
try {
cursor.close();
} catch (DatabaseException e) {
e.printStackTrace();
}
}
if (txn != null) {
try {
txn.commitNoSync();
} catch (DatabaseException e) {
e.printStackTrace();
}
}
}
return list;
}
/**
* 删除范围的值
*
* @param start
* @param end
*/
public void deleteRange(long start, long end) {
Cursor cursor = null;
Transaction txn = null;
try {
txn = databaseEnv.beginTransaction(null, null);
CursorConfig config = new CursorConfig();
config.setReadCommitted(true);
cursor = cacheDatabase.openCursor(txn, config);
DatabaseEntry theKey = new DatabaseEntry(("" + start)
.getBytes("UTF-8"));
DatabaseEntry theData = new DatabaseEntry();
OperationStatus retVal = cursor.getSearchKeyRange(theKey, theData,
LockMode.DEFAULT);
// 有记录,删除之
if (cursor.count() >= 1) {
while (retVal == OperationStatus.SUCCESS) {
String keyString = new String(theKey.getData(), "UTF-8");
long timeStamp = Long.parseLong(keyString);
if (timeStamp >= start && timeStamp < end) {
cursor.delete();
retVal = cursor.getNext(theKey, theData,
LockMode.DEFAULT);
} else {
break;
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (cursor != null) {
try {
cursor.close();
} catch (DatabaseException e) {
e.printStackTrace();
}
}
if (txn != null) {
try {
txn.commitNoSync();
} catch (DatabaseException e) {
e.printStackTrace();
}
}
}
}
public String getDatabasePath() {
if (StringUtil.isBlank(this.databasePath)) {
databasePath = DB_ENVIRONMENT_ROOT;
}
return databasePath;
}
public void setDatabasePath(String databasePath) {
this.databasePath = databasePath;
}
public static void main(String[] args) {
BerkeleyDBServiceImpl bService = new BerkeleyDBServiceImpl();
bService.init();
User u1 = new User(Integer.valueOf(1), "luohua");
User u2 = new User(Integer.valueOf(2), "kiko");
User u3 = new User(Integer.valueOf(3), "baby");
bService.putObject(u1.getId().toString(), u1);
bService.putObject(u2.getId().toString(), u2);
bService.putObject(u3.getId().toString(), u3);
User temp1 = (User) bService.getObject(u1.getId().toString());
System.out.println(temp1);
bService.deleteRange(1, 3);
List list = bService.searchRange(1, 5);
System.out.println(list.size());
bService.delete("3");
bService.destroy();
}
}
修改了每次存放一个对象,
同时增加了对key的范围搜索和范围删除
参考了同事的部分代码,优化了配置,同时修复了以下问题:
1、取数据没有数据时报nullpoint的错误
2、搜索数据没有关闭transaction的错误
package com.sillycat.plugin.berkeley.impl;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import com.sillycat.core.model.User;
import com.sillycat.plugin.commons.utils.StringUtil;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.serial.SerialBinding;
import com.sleepycat.bind.serial.StoredClassCatalog;
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.DatabaseException;
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;
public class BerkeleyDBServiceImpl {
// 数据库的默认路径
private static final String DB_ENVIRONMENT_ROOT = "D:/dbRoot";
// 数据库环境
private Environment databaseEnv;
// 数据
private static Database cacheDatabase;
// 类
private static Database classBindingDatabase;
// 数据绑定的环境
private EntryBinding dataBinding;
// 数据库路径
private String databasePath;
/**
* 初始化数据参数
*/
public void init() {
try {
EnvironmentConfig config = new EnvironmentConfig();
config.setAllowCreate(true);// 如果不存在则创建一个
config.setReadOnly(false); // 以只读方式打开,默认为false
config.setTransactional(true); // 事务支持,如果为true,则表示当前环境支持事务处理,默认为false,不支持事务处理
databaseEnv = new Environment(new File(this.getDatabasePath()),
config);
DatabaseConfig dbConfig = new DatabaseConfig();
dbConfig.setAllowCreate(true);
dbConfig.setTransactional(true);
// 初始化缓存数据库
cacheDatabase = databaseEnv.openDatabase(null, "cacheDatabase",
dbConfig);
classBindingDatabase = databaseEnv.openDatabase(null,
"classDatabase", dbConfig);
StoredClassCatalog classCatalog = new StoredClassCatalog(
classBindingDatabase);
dataBinding = new SerialBinding(classCatalog, Object.class);
} catch (DatabaseException e) {
e.printStackTrace();
}
}
/**
*
* 关闭database环境
*/
public void destroy() {
try {
if (cacheDatabase != null) {
cacheDatabase.close();
}
if (classBindingDatabase != null) {
classBindingDatabase.close();
}
if (databaseEnv != null) {
databaseEnv.cleanLog(); // 在关闭环境前清理下日志
databaseEnv.close();
}
} catch (DatabaseException e) {
e.printStackTrace();
}
}
/**
* 放入对象
*
* @param key
* @param obj
*/
public void putObject(String key, Object obj) {
DatabaseEntry theKey;
try {
DatabaseEntry theData = new DatabaseEntry();
theKey = new DatabaseEntry(key.getBytes("UTF-8"));
dataBinding.objectToEntry(obj, theData);
cacheDatabase.put(null, theKey, theData);
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
} catch (DatabaseException e) {
e.printStackTrace();
}
}
/**
* 取出对象
*
* @param key
* @return
* @throws DatabaseException
* @throws UnsupportedEncodingException
*/
public Object getObject(String key) {
DatabaseEntry theKey;
Object retData = null;
try {
theKey = new DatabaseEntry(key.getBytes("UTF-8"));
DatabaseEntry theData = new DatabaseEntry();
cacheDatabase.get(null, theKey, theData, LockMode.DEFAULT);
if (theData.getSize() > 0) {
retData = (Object) dataBinding.entryToObject(theData);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (DatabaseException e) {
e.printStackTrace();
}
return retData;
}
/**
* 删除数据
*
* @param key
*/
public void delete(String key) {
DatabaseEntry theKey;
try {
theKey = new DatabaseEntry(key.getBytes("UTF-8"));
cacheDatabase.delete(null, theKey);
// 删除数据
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (DatabaseException e) {
e.printStackTrace();
}
}
/**
*
* 搜索范围内的数据
*
* @param begin
* @param end
* @return
* @throws DatabaseException
* @throws UnsupportedEncodingException
*/
public List searchRange(long begin, long end) {
List list = null;
Cursor cursor = null;
Transaction txn = null;
try {
txn = databaseEnv.beginTransaction(null, null);
CursorConfig config = new CursorConfig();
config.setReadCommitted(true);
cursor = cacheDatabase.openCursor(txn, config);
DatabaseEntry theKey = new DatabaseEntry((begin + "")
.getBytes("UTF-8"));
DatabaseEntry theData = new DatabaseEntry();
OperationStatus retVal = cursor.getSearchKeyRange(theKey, theData,
LockMode.DEFAULT);
// 如果count超过一个,则遍历
if (cursor.count() >= 1) {
list = new ArrayList();
while (retVal == OperationStatus.SUCCESS) {
String keyString = new String(theKey.getData(), "UTF-8");
String dataString = new String(theData.getData(), "UTF-8");
// retVal = cursor.getNextDup(theKey, theData,
// LockMode.DEFAULT);
long timeStamp = Long.parseLong(keyString);
if (timeStamp >= begin && timeStamp < end) {
list.add(dataString);
retVal = cursor.getNext(theKey, theData,
LockMode.DEFAULT);
} else {
break;
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (cursor != null) {
try {
cursor.close();
} catch (DatabaseException e) {
e.printStackTrace();
}
}
if (txn != null) {
try {
txn.commitNoSync();
} catch (DatabaseException e) {
e.printStackTrace();
}
}
}
return list;
}
/**
* 删除范围的值
*
* @param start
* @param end
*/
public void deleteRange(long start, long end) {
Cursor cursor = null;
Transaction txn = null;
try {
txn = databaseEnv.beginTransaction(null, null);
CursorConfig config = new CursorConfig();
config.setReadCommitted(true);
cursor = cacheDatabase.openCursor(txn, config);
DatabaseEntry theKey = new DatabaseEntry(("" + start)
.getBytes("UTF-8"));
DatabaseEntry theData = new DatabaseEntry();
OperationStatus retVal = cursor.getSearchKeyRange(theKey, theData,
LockMode.DEFAULT);
// 有记录,删除之
if (cursor.count() >= 1) {
while (retVal == OperationStatus.SUCCESS) {
String keyString = new String(theKey.getData(), "UTF-8");
long timeStamp = Long.parseLong(keyString);
if (timeStamp >= start && timeStamp < end) {
cursor.delete();
retVal = cursor.getNext(theKey, theData,
LockMode.DEFAULT);
} else {
break;
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
} finally {
if (cursor != null) {
try {
cursor.close();
} catch (DatabaseException e) {
e.printStackTrace();
}
}
if (txn != null) {
try {
txn.commitNoSync();
} catch (DatabaseException e) {
e.printStackTrace();
}
}
}
}
public String getDatabasePath() {
if (StringUtil.isBlank(this.databasePath)) {
databasePath = DB_ENVIRONMENT_ROOT;
}
return databasePath;
}
public void setDatabasePath(String databasePath) {
this.databasePath = databasePath;
}
public static void main(String[] args) {
BerkeleyDBServiceImpl bService = new BerkeleyDBServiceImpl();
bService.init();
User u1 = new User(Integer.valueOf(1), "luohua");
User u2 = new User(Integer.valueOf(2), "kiko");
User u3 = new User(Integer.valueOf(3), "baby");
bService.putObject(u1.getId().toString(), u1);
bService.putObject(u2.getId().toString(), u2);
bService.putObject(u3.getId().toString(), u3);
User temp1 = (User) bService.getObject(u1.getId().toString());
System.out.println(temp1);
bService.deleteRange(1, 3);
List list = bService.searchRange(1, 5);
System.out.println(list.size());
bService.delete("3");
bService.destroy();
}
}