`

Berkely DB Java Edition学习笔记一

阅读更多
Berkely DB对于高并发、要求速度快的应用来说是个不错的选择,mysql就是用BDB实现的(mysql的后台) ,mysql快,BDB比mysql还要快N倍。BDB是一种嵌入式的、非关系数据库,它与其他的关系数据库RMDBS不同,它没有提供SQL,而是提供了自己的访问接口。作为一种嵌入式的数据库,它是进程内模式的,也就是说它和应用程序在同一内存空间运行,所以速度要高很多,与嵌入式的数据库如Derby、HSQLDB(都是RMDBS的)相比,它效率更高,使用方法也有很大的不同。现在BDB以被Oracle收购。Berkely DB提供的文档Getting Started with Berkeley DB Java Edition可以说是短小精悍(113页),入门相当不错。下面Get Start吧:
Environment:
首先要接触的就是Environment了,使用它来open database以及做一管理方面的事情.
创建Environment,还需要Environment的一些配置信息EnvironmentConfig。
下面是创建的过程:
EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setAllowCreate(true);
myDbEnvironment = new Environment(new File("/export/dbEnv"),
envConfig);

其中EnvironmentConfig提供了许多配置参数,常用的有:
envConfig.setAllowCreate()//如果不存在的env的话,是否要创建一个新的
envConfig.setReadOnly()//是否为只读的
envConfig.setTransactional()//是否使用事务
参数都是boolean类型的
除了EnvironmentConfig外,还有EnvironmentMutableConfig,他实际是EnvironmentConfig的父类,使用他来配置在创建完Environment之后可以改变
的属性:
setCachePercent()//设置cache的大小占JVM memory的百分比
setCacheSize()//设置cache的大小
setTxnNoSync()//事务提交是否将改变的记录写入磁盘
setTxnWriteNoSync()//事务提交是否将log写入磁盘
下面看一下使用EnvironmentMutableConfig的方法:
Environment myEnv = new Environment(new File("/export/dbEnv"), null);
EnvironmentMutableConfig envMutableConfig =
new EnvironmentMutableConfig();
envMutableConfig.setTxnNoSync(true);
myEnv.setMutableConfig(envMutableConfig);

Environment通过close来关闭,释放资源
下面看看Environment在管理方面的一些方法:
可以通过Environment获得EnvironmentStats,他提供了Environment一些状态信息,
例如使用
long cacheMisses = myEnv.getStats(null).getNCacheMiss();

我们可以获得cache未命中的次数,据此来调整cache的大小
可以同过Environment.getDatabaseNames()来获得Environment的数据库的名字:
List myDbNames = myDbEnv.getDatabaseNames();
for(int i=0; i < myDbNames.size(); i++) {
System.out.println("Database Name: " + (String)myDbNames.get(i));
}

可以通过Environment.removeDatabase()来删除一个数据库:
String dbName = myDB.getDatabaseName();
myDB.close();
myDBEnv.removeDatabase(null,dbName);

可以使用Environment.renameDatabase()来重新命名一个数据库:
String dbName = myDB.getDatabaseName();
String dbNewName = new String(dbName + ".new", "UTF-8");
myDB.close();
myDBEnv.renameDatabase(null,dbName,dbNewName);

可以使用Environment.truncateDatabase()来删除数据库中的所有记录:
myEnv.truncate(null, // txn handle
myDatabase.getDatabaseName(), // database name
true//whether to return the count of deleted records
);

第三个参数是否返回删除的记录数,性能有很大不同。false的话会很快
Database:
最重要的一些操作大多都在Database里了,和Environment一样,它也有许多
配置的选项DatabaseConfig,我们先看看选项:
DatabaseConfig.setAllowCreate()//不能存在的话是open操作否创建新的
DatabaseConfig.setBtreeComparator()//设置Btree的比较器
DatabaseConfig.setDuplicateComparator()//设置判断重复的比较器
DatabaseConfig.setSortedDuplicates()//是否允许重复的记录
DatabaseConfig.setExclusiveCreate()//设为true,如果当前数据库已存在,则open失败,也就是说open操作会导致一个新的数据库被创建,默认为false
DatabaseConfig.setReadOnly()//是否是只读的
DatabaseConfig.setTransactional()//是否使用事务
下面我们看看Database的使用流程:
EnvironmentConfig envConfig = new EnvironmentConfig();
envConfig.setAllowCreate(true);
myDbEnvironment = new Environment(new File("/export/dbEnv"), envConfig);
DatabaseConfig dbConfig = new DatabaseConfig();
dbConfig.setAllowCreate(true);
myDatabase = myDbEnvironment.openDatabase(null,
"sampleDatabase",
dbConfig);

我们通过Environment的openDatabase来创建Database对象。使用完了Database使用
close方法来关闭数据库释放资源。
Database Records
Database Record是保存在数据库的内容,包含Key和value两部分,他们都被封装成
DatabaseEntry,DatabaseEntry只能存放字节数组,所以只要能把Key和Value是什么
类型的,只要能转化成字节数组就可以被DatabaseEntry封装。基本类型JE都有对应的Binding,复杂的类型可以使用序列化和自定义binding来实现。
下那面我们看看一个使用方法:
String aKey = "key";
String aData = "data";
try {
DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
DatabaseEntry theData = new DatabaseEntry(aData.getBytes("UTF-8"));
} catch (Exception e) {
}

我们不应该依赖机器默认的编码,通常要指定特定的编码方法getBytes("UTF-8");
我们先看看怎么从数据库中读写记录:
通过Database.put()和Database.get()我们可以从数据库中读写记录
put:
String aKey = "myFirstKey";
String aData = "myFirstData";
try {
DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
DatabaseEntry theData = new DatabaseEntry(aData.getBytes("UTF-8"));
myDatabase.put(null, theKey, theData);
} catch (Exception e) {
}

get:
String aKey = "myFirstKey";
try {
DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
DatabaseEntry theData = new DatabaseEntry();

if (myDatabase.get(null, theKey, theData, LockMode.DEFAULT) ==
OperationStatus.SUCCESS) {

byte[] retData = theData.getData();
String foundData = new String(retData, "UTF-8");
System.out.println("For key: '" + aKey + "' found data: '" +
foundData + "'.");
} else {
  System.out.println("No record found for key '" + aKey + "'.");
}
} catch (Exception e) {
}

删除操作:
String aKey = "myFirstKey";
DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
myDatabase.delete(null, theKey);

使用BIND APIs来操作基本类型:
我们可以使用JE提供的Bind Apis来操作数字类型和字符串类型:
以Long为例:
存储数据使用Bind Apis一般步骤如下:
1、通过EntryBinding binding =TupleBinding.getPrimitiveBinding(Long.class);
2、通过EntryBinding 把数据放到DatabaseEntry中:
myBinding.objectToEntry(data, dataEntry);
获取数据使用Bind Apis一般步骤如下:
1、通过EntryBinding binding =TupleBinding.getPrimitiveBinding(Long.class);
2、通过EntryBinding将Entry转换成Object Long theLong = (Long) myBinding.entryToObject(theData);
下面代码以测试的形式演示了整个过程:
package edu.jlu.fuliang;

import java.io.File;

import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.tuple.TupleBinding;
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 junit.framework.TestCase;

public class PrimitiveBindingTest extends TestCase{
	private Environment env;
	private Database db;
	private String key = "akey";
	private Long data = 1234556633L;
	
	public void setUp()throws Exception{
		EnvironmentConfig envConfig = new EnvironmentConfig();
		envConfig.setAllowCreate(true);
		env = new Environment(new File("etc/dbEnv"),envConfig);
		DatabaseConfig dbConfig = new DatabaseConfig();
		dbConfig.setAllowCreate(true);
		db = env.openDatabase(null, "myDB", dbConfig);
		DatabaseEntry keyEntry = new DatabaseEntry(key.getBytes("UTF-8"));
		DatabaseEntry dataEntry = new DatabaseEntry();
		
		EntryBinding myBinding = TupleBinding.getPrimitiveBinding(Long.class);
	    myBinding.objectToEntry(data, dataEntry);
	    db.put(null, keyEntry, dataEntry);
	}
	
	public void testGet()throws Exception{
		DatabaseEntry keyEntry = new DatabaseEntry(key.getBytes("UTF-8"));
		DatabaseEntry dataEntry = new DatabaseEntry();
		EntryBinding binding = TupleBinding.getPrimitiveBinding(Long.class);
		db.get(null, keyEntry, dataEntry, LockMode.DEFAULT);
		Long l = (Long)binding.entryToObject(dataEntry);
		assertEquals(l,data);
	}
	public void tearDown()throws Exception{
		db.close();
		env.truncateDatabase(null, "myDB",false);
		env.close();
	}
	
}

序列化复杂的类型
步骤如下:
1、要存储的对象的类需要实现java.io.Serializable
2、打开两个数据库,一个存放数据,另一个存放类的信息
3、实例化com.sleepycat.bind.serial.StoredClassCatalog对象
4、创建uses com.sleepycat.bind.serial.SerialBinding对象
5、使用SerialBinding把对象放到DatabaseEntry中
下面是使用一个能够完整描述这个过程的例子来说明这个过程:
package edu.jlu.fuliang;

import java.io.File;

import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.serial.SerialBinding;
import com.sleepycat.bind.serial.StoredClassCatalog;
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 junit.framework.TestCase;

public class SerializableTypeTest extends TestCase{
	private Person person;
	private Environment env;
	private Database db,classDB;
	private StoredClassCatalog classCatalog;
	
	public void setUp()throws Exception{
		person = new Person();
		person.setAge(12);
		person.setName("zhansan");
		person.setSex('m');
	    
		EnvironmentConfig envConfig = new EnvironmentConfig();
		envConfig.setAllowCreate(true);
		env = new Environment(new File("etc/dbEnv"),envConfig);
		DatabaseConfig dbConfig = new DatabaseConfig();
		dbConfig.setAllowCreate(true);
		db = env.openDatabase(null, "myDB", dbConfig);
		classDB = env.openDatabase(null, "classDB", dbConfig);
		classCatalog = new StoredClassCatalog(classDB);
		EntryBinding dataBinding = new SerialBinding(classCatalog,Person.class);
			
		DatabaseEntry keyEntry = new DatabaseEntry(person.getName().getBytes("UTF-8"));
		DatabaseEntry dataEntry = new DatabaseEntry();
		dataBinding.objectToEntry(person, dataEntry);
		db.put(null, keyEntry, dataEntry);
	}
	
	public void testGet()throws Exception{
		EntryBinding dataBinding = new SerialBinding(classCatalog,Person.class);
	  
		DatabaseEntry keyEntry = new DatabaseEntry(person.getName().getBytes("UTF-8"));
	    DatabaseEntry dataEntry = new DatabaseEntry();
	    db.get(null, keyEntry, dataEntry, LockMode.DEFAULT);
	    Person p = (Person)dataBinding.entryToObject(dataEntry);
	    assertEquals(p.getName(),person.getName());
	    assertEquals(p.getAge(),person.getAge());
	    assertEquals(p.getSex(), person.getSex());
	}
	
	public void tearDown()throws Exception{
		db.close();
		classDB.close();
		env.truncateDatabase(null, "myDB", false);
		env.truncateDatabase(null, "classDB", false);
		env.close();
	}
}

要存储的对象对应的类
package edu.jlu.fuliang;

import java.io.Serializable;

public class Person implements Serializable{
	private String name;
	private int age;
	private char sex;

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public char getSex() {
		return sex;
	}

	public void setSex(char sex) {
		this.sex = sex;
	}
}

自定义元组绑定:
存储复杂对象自定义元组绑定的步骤:
1、创建要存储的对象,这个对象的类没有必要实现Serializable接口:
2、扩展com.sleepycat.bind.tuple.TupleBinding来实现自定义的Binging
3、创建2步欻关键的自定义binding对象
4、将创建的对象是用自定义个binding放到DatabaseEntry中
5、使用put方法存入数据库
下面的例子说明了这个过程:
自定义Binging:
package edu.jlu.fuliang;

import com.sleepycat.bind.tuple.TupleBinding;
import com.sleepycat.bind.tuple.TupleInput;
import com.sleepycat.bind.tuple.TupleOutput;

public class PersonTupleBinding extends TupleBinding{

	@Override
	public Object entryToObject(TupleInput ti) {
		Person person = new Person();
		person.setName(ti.readString());
		person.setAge(ti.readInt());
		person.setSex(ti.readChar());
		return person;
	}

	@Override
	public void objectToEntry(Object obj, TupleOutput output) {
		Person person = (Person)obj;
		output.writeString(person.getName());
		output.writeInt(person.getAge());
		output.writeChar(person.getSex());
	}
}

put/get的使用过程:
package edu.jlu.fuliang;

import java.io.File;
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 junit.framework.TestCase;

public class CustomTupleBindingTest extends TestCase{
	private Person person;
	private Environment env;
	private Database db;
	
	public void setUp()throws Exception{
		person = new Person();
		person.setAge(12);
		person.setName("zhansan");
		person.setSex('m');
	    
		
		EnvironmentConfig envConfig = new EnvironmentConfig();
		envConfig.setAllowCreate(true);
		env = new Environment(new File("etc/dbEnv"),envConfig);
		DatabaseConfig dbConfig = new DatabaseConfig();
		dbConfig.setAllowCreate(true);
		db = env.openDatabase(null, "myDB", dbConfig);
		PersonTupleBinding binding = new PersonTupleBinding();
		DatabaseEntry keyEntry = new DatabaseEntry(person.getName().getBytes("UTF-8"));
		DatabaseEntry dataEntry = new DatabaseEntry();
		binding.objectToEntry(person, dataEntry);
		db.put(null, keyEntry, dataEntry);
		
	}
	
	public void testGet()throws Exception{
		PersonTupleBinding binding = new PersonTupleBinding();
	    
		DatabaseEntry keyEntry = new DatabaseEntry(person.getName().getBytes("UTF-8"));
	    DatabaseEntry dataEntry = new DatabaseEntry();
	    db.get(null, keyEntry, dataEntry, LockMode.DEFAULT);
	    Person p = (Person)binding.entryToObject(dataEntry);
	    assertEquals(p.getName(),person.getName());
	    assertEquals(p.getAge(),person.getAge());
	    assertEquals(p.getSex(), person.getSex());
	}
	public void tearDown()throws Exception{
		db.close();
		env.truncateDatabase(null, "myDB", false);
		env.close();
	}
}
8
3
分享到:
评论
2 楼 fuliang 2009-03-16  
alanye 写道

您好,请问DatabaseConfig原来有setType,可以选择BTree或者是Hash或者别的,新的je.DatabaseConfig里面没有了,是不是只能选择BTree呢? 谢谢

不太清楚,你可以看看新版本更新的说明。
1 楼 alanye 2009-03-16  
您好,请问DatabaseConfig原来有setType,可以选择BTree或者是Hash或者别的,新的je.DatabaseConfig里面没有了,是不是只能选择BTree呢? 谢谢

相关推荐

    Berkeley DB Java Edition学习报告

    Berkeley DB Java Edition (JE) 是一款开源的嵌入式数据库管理系统,由Sleepycat Software开发,现归Oracle公司所有。这款数据库系统以其键值(K/V)存储模型为特色,适用于需要高性能、可伸缩性及事务处理能力的应用...

    Berkeley DB Java Edition (JE)

    Berkeley DB Java Edition (JE) 官方7.5.11下载版本。 相关介绍 https://blog.csdn.net/hadues/article/details/80854288

    Berkeley DB Java Edition

    **Berkeley DB Java Edition**,简称BDBJE,是由Oracle公司开发的一款高度可移植的、基于文件系统的数据存储解决方案,特别适用于需要高效、可靠且无服务器的数据管理的应用场景。这款数据库系统采用B+树作为其核心...

    Berkeley DB Java Edition 5.0.73

    Berkeley DB Java Edition(简称BDB JE)是一款由Oracle公司开发的高性能、轻量级的NoSQL数据库系统。它以其高效能、可扩展性和可靠性在处理大规模数据存储时受到广泛欢迎,尤其是在Google这样的大型互联网公司中,...

    Berkeley DB Java Edition数据结构的研究与应用.pdf

    Berkeley DB Java Edition(JE)是一种为Java程序提供内嵌式、事务保护的数据库引擎,它继承了Berkeley DB家族的优点,包括快速、可靠和具备容错能力的数据管理特性。为了深入理解其数据存储结构,有必要对JE使用的B...

    Berkeley DB的java版本

    Berkeley DB Java Edition JE 是一个完全用JAVA写的 它适合于管理海量的 简单的数据 能够高效率的处理1到1百万条记录 制约JE数据库的往往是硬件系统 而不是JE本身 多线程支持 JE使用超时的方式来处理线程间的死琐...

    Berkeley DB Java Edition 4.1.10.zip

    Berkeley DB Java Edition (JE)是一个完全用JAVA写的,它适合于管理海量的,简单的数据。 能够高效率的处理1到1百万条记录,制约JE数据库的往往是硬件系统,而不是JE本身。 多线程支持,JE使用超时的方式来处理...

    Berkeley DB Java Edition 4.0.92 开发包

    Berkeley DB Java Edition(简称BDB JE)是Oracle公司推出的一款强大的、高度可定制的嵌入式数据库系统,尤其适用于Java应用程序。这款数据库引擎以其轻量级、高性能和易用性在Java企业开发领域广受欢迎。本文将深入...

    Java嵌入式NoSQL数据库之Berkeley DB Java Edition

    Berkeley DB Java Edition(简称BDB JE)是一种高性能、轻量级的嵌入式数据库系统,由Oracle公司开发,广泛应用于需要快速数据存储和检索的应用场景。它并非传统的关系型数据库管理系统(RDBMS),而是一种键值对...

    Berkeley DB Java 版 4.0.92

    Oracle Berkeley DB Java 版是一个开源的、可嵌入的事务存储引擎,是完全用 Java 编写的。与 Oracle Berkeley DB 类似,Oracle Berkeley DB Java 版在应用程序的地址空间中执行,没有客户端/服务器通信的开销,从而...

    Berkeley DB Java Edition初步

    NULL 博文链接:https://xpenxpen.iteye.com/blog/2124921

    BerkeleyDB_java_jar包

    这可能是BerkeleyDB Java Edition的jar文件,表示BerkeleyDB Java版的7.5.11版本。这个文件通常会包含以下组件: 1. **BerkeleyDB引擎**:这是数据库的核心部分,处理数据的读写操作,包括事务处理、并发控制、恢复...

    berkeley db java

    自己稍微封装了一下,可以当成简单的map来使用。

    Berkeley DB Java 版直接持久层基础1

    Berkeley DB Java 版直接持久层基础1 Berkeley DB Java 版直接持久层基础1是指使用 Berkeley DB Java 版本来实现直接持久层的技术基础。直接持久层是一种数据访问技术,允许Java应用程序直接访问数据库,而不需要...

    嵌入式Berkeley DB Java版与Derby技术研究.pdf

    Berkeley DB Java Edition(简称BDBJE)是由Oracle公司开发的一款轻量级、高性能的键值存储数据库。它提供了基于Java的API,可以方便地集成到Java应用程序中。BDBJE的核心特点是其简单且高效的接口,允许开发者以...

    Java-Edition-BerkeleyDB-3.1.0.zip_BerkeleyDB

    总结来说,Java-Edition-BerkeleyDB-3.1.0是一个强大且灵活的数据库解决方案,特别适合对数据访问速度和并发性能有高要求的Java应用。其易用的API、丰富的功能集以及高度的可定制性使其成为许多开发者的首选。

Global site tag (gtag.js) - Google Analytics