Berkeley DB是一个嵌入式数据库,适合于管理海量的、简单的数据。

键值对(key/value)数据存储方式使Berkeley DB用来进行数据库管理的基础,每个key/value构成一条记录。
Berkeley的数据库主要就是put和get,前者存入键值对,后者根据键获取值。

因为Berkeley DB的数据库操作有些复杂,所以将其封装成了一个简单的类:

package ch01_3;

import java.io.File;
import java.util.AbstractMap.SimpleEntry;
import java.util.ArrayList;
import java.util.Map.Entry;

import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.serial.SerialBinding;
import com.sleepycat.bind.serial.StoredClassCatalog;
import com.sleepycat.collections.StoredMap;
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;

/*********************************
 * 使用BerkeleyDB封装了一些数据库操作
 * 包括设置缓冲区,设置编码,设置数据可库
 * 路径,存储键值对,根据键查找值,关闭数
 * 据库等操作。
 * @author Administrator
 *********************************/
public class MyBerkeley {
	
	private Environment environment;	//环境
	private Database	database;		//数据库
	@SuppressWarnings("unused")
	private String 		charset;		//编码
	private String 		path;			//路径
	private long        chacheSize;		//缓冲区大小
	
	private StoredMap<Object, Object> 	pendingDB = null;	
	private Object keyClass = String.class;			//设置默认的key值类型
	private Object valueClass = Integer.class;		//设置默认的value值类型
	
	public MyBerkeley(){
		charset = "UTF-8";		//编码默认使用UTF-8
		chacheSize = 10000;		//缓冲区大小默认为10000
	}
	
	//设置编码
	public void setCharset(String charset)
	{
		this.charset = charset;
	}
	
	//设置路径
	public void setPath(String path){
		//判断Path是否存在
		File file = new File(path);
		if(file.mkdir()){
			System.out.println(path+"已创建!"); //不存在则创建一个
		}
		else{
			System.out.println(path+"已存在!"); //存在则说明已存在
		}
		
		//确定存储路径
		this.path = path;
	}
	
	//设置缓冲区大小
	public boolean setChacheSize(long size){
		if(size<=0 || size >=1000000000)
		{
			return false; //使用默认的大小
		}
		this.chacheSize = size;
		return true;
	}
	
	//同时设置路径和缓冲区
	public void setEnvironment(String path , long chacheSize){
		setPath(path);
		setChacheSize(chacheSize);
		//配置环境
		EnvironmentConfig envConfig = new EnvironmentConfig();
		envConfig.setAllowCreate(true);
		envConfig.setCacheSize(this.chacheSize);
		//创建环境
		environment = new Environment(new File(this.path),envConfig);
	}
	
	//设置存储类型
	public void setClassType(Object keyClass,Object valueClass)
	{
		this.keyClass = keyClass;
		this.valueClass = valueClass;
	}
	
	//打开名字是dbName的数据库
	@SuppressWarnings("unchecked")
	public void open(String dbName)
	{
		DatabaseConfig dbConfig = new DatabaseConfig();
		dbConfig.setAllowCreate(true);
		dbConfig.setSortedDuplicates(false); //不存储重复关键字
		this.database = environment.openDatabase(null, dbName, dbConfig);
		//初始化存储序列化对象的catalog类
		StoredClassCatalog catalog = new StoredClassCatalog(database);
		//键值都使用序列化的方式进行存储
		EntryBinding<Object> keyBinding = new SerialBinding<Object>(catalog,(Class<Object>) keyClass);
		EntryBinding<Object> valueBinding = new SerialBinding<Object>(catalog,(Class<Object>) valueClass);
		//创建数据存储的映射视图
		pendingDB = new StoredMap<Object, Object>(database,keyBinding,valueBinding,true);
	}
	
	//关闭
	public void close()
	{
		database.close();
		environment.close();
	}
	
	//存储
	public void put(Object key,Object value)
	{
		pendingDB.put(key, value);
	}
	
	//取值
	public Object get(Object key)
	{
		return pendingDB.get(key);
	}
	
	//按照键值删除数据
	public Object del(Object key)
	{
		return pendingDB.remove(key);
	}
	
	//获取数据库存储数据的大小
	public int size()
	{
		return pendingDB.size();
	}
	
	//遍历数据库
	public ArrayList<Entry<Object,Object>> getAllItems()
	{
		Cursor cursor = null;//游标
		ArrayList<Entry<Object,Object>> result = new ArrayList<Entry<Object,Object>>();
		CursorConfig cConfig = new CursorConfig();
		if(cursor == null)
			cursor = database.openCursor(null, cConfig);
		DatabaseEntry theKey = new DatabaseEntry();
		DatabaseEntry theValue = new DatabaseEntry();
		//使用Cursor.getPerv方法来遍历游标获取数据
		if(cursor.getFirst(theKey, theValue, LockMode.DEFAULT)
				== OperationStatus.SUCCESS)
		{
			Object key = theKey.getData();
			Object value = theValue.getData();
			Entry<Object,Object> entry = new SimpleEntry<Object,Object>(key,value);
			result.add(entry);
			while(cursor.getNext(theKey, theValue, LockMode.DEFAULT)
					== OperationStatus.SUCCESS)
			{
				key = theKey.getData();
				value = theValue.getData();
				entry = new SimpleEntry<Object,Object>(key,value);
				result.add(entry);
			}
		}
		cursor.close();//关闭游标
		return result;
	}
	
	public static void main(String[] args) throws Exception {
		   MyBerkeley db = new MyBerkeley();
		   db.setEnvironment("C:\\BerkeleyDB\\MyDatabase2", 1000000);
		   //设置存储类型(包括键和值)
		   db.setClassType(String.class, String.class);
		   db.open("myDB");//打开数据库
		   
		   //存储值与取值测试
		   /*
		   for(int i=10; i>=0; i--) {
			     String key = "Key"+i;
			     String value = ""+i;
			     db.put(key , value);
			     System.out.println("[" + key + ":" + db.get(key) + "]");
		   }//*/
		   //获取数据库键值对数量
		   System.out.println(db.size());
		   //删除数据测试
		   db.del("Key3");
		   //遍历数据库测试
		   ArrayList<Entry<Object,Object>> r = db.getAllItems();
		   for(int i=0;i<r.size();i++)
		   {
			   String key = new String((byte[]) r.get(i).getKey());
			   String value = new String((byte[]) r.get(i).getValue(),"UTF-8");
			   System.out.println(key+":"+value);
		   }
		   db.close();
		}
}