引见和使用Berkeley DB Java Edition(嵌入式数据库)

介绍和使用Berkeley DB Java Edition(嵌入式数据库)一、 简介 ?????? Berkeley DB Java Edition (JE)是一个

介绍和使用Berkeley DB Java Edition(嵌入式数据库)

一、 简介

?????? Berkeley DB Java Edition (JE)是一个完全用JAVA写的,它适合于管理海量的,简单的数据。

??????? 能够高效率的处理1到1百万条记录,制约JE数据库的往往是硬件系统,而不是JE本身。

??????? 多线程支持,JE使用超时的方式来处理线程间的死琐问题。

??????? Database都采用简单的key/value对应的形式。

??????? 事务支持。
??????? 允许创建二级库。这样我们就可以方便的使用一级key,二级key来访问我们的数据。

??????? 支持RAM缓冲,这样就能减少频繁的IO操作。

??????? 支持日志。

??????? 数据备份和恢复。

??????? 游标支持。

二、?? 获取JE

JE下载地址:

http://www.oracle.com/technology/software/products/berkeley-db/je/index.html

解开包后 把JE_HOME/lib/je-<version>.jar 中的jar文件添加到你的环境变量中就可以使用je了。

相关帮助文档可以参考 JE_HOME/docs/index.html

源代码见JE_HOME/src/*.*

三、???? JE常见的异常

DatabaseNotFoundException 当没有找到指定的数据库的时候会返回这个异常

DeadlockException 线程间死锁异常

RunRecoveryException 回收异常,当发生此异常的时候,你必须得重新打开环境变量。

四、???? 关于日志文件必须了解的六项

JE的日志文件跟其他的数据库的日志文件不太一样,跟C版的DBD也是有区别的

??????? JE的日志文件只能APPEND,第一个日志文件名是 00000000.jdb,当他增长到一定大小的时候(默认是10M),开始写第二个日志文件00000001.jdb,已此类推。

??????? 跟C版本有所不同,JE的数据日志和事务日志是放在一起的,而不是分开放的。

??????? JE cleaner负责清扫没用到的磁盘空间,删除后,或者更新后新的记录会追加进来,而原有的记录空间就不在使用了,cleaner负责清理不用的空间。

??????? 清理并不是立即进行的,当你关闭你的数据库环境后,通过调用一个cleaner方法来清理。

?????? 清理也不是只动执行的,需要你自己手动调用cleaner 方法来定时清理的。

??????? 日志文件的删除仅发生在检查点之后。cleaner准备出哪些log 文件需要被删除,当检查点过后,删掉一些不在被使用的文件。每写20M的日志文件就执行一次检查点,默认下。

JE的英文文档:http://www.oracle.com/technology/documentation/berkeley-db/je/GettingStartedGuide/index.html

JE的中文文档(不全):http://fesir.itpub.net/post/4728/253789
http://fesir.itpub.net/post/4728/253789

上面大概介绍一下,接下来是我在工作中写的一个例子(仅供参考):

Java代码 view plaincopy to clipboardprint?
package src.util;??
?
import java.io.File;??
import java.util.List;??
?
import junit.framework.TestCase;??
import src.com.bizjato.b2b.entity.Suppliers;??
?
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.EnvironmentMutableConfig;??
import com.sleepycat.je.LockMode;??
import com.sleepycat.je.OperationStatus;??
?
/**?
?* 嵌入式数据库?
?*??
?* @author zhangqinjian?
?*?
?*/?
public class Jedtion extends TestCase {??
?
??? private static final String RESOURCE = ".//src//util//importData";??
??? private Environment env;??
?
??? private Database db, classDB;??
?
??? private StoredClassCatalog classCatalog;??
??? /**?
???? * 初始化,设置数据库的环境和创建数据库?
???? */?
??? public void setUp() throws Exception {??
?
??????? env = new Environment(new File(".//src//util//importData"), null);??
??????? EnvironmentMutableConfig envMutableConfig = new EnvironmentMutableConfig();??
??????? envMutableConfig.setTxnNoSync(true);??
??????? env.setMutableConfig(envMutableConfig);??
?
??????? DatabaseConfig dbConfig = new DatabaseConfig();??
??????? dbConfig.setAllowCreate(true);??
??????? db = env.openDatabase(null, "myDB", dbConfig);??
??????? classDB = env.openDatabase(null, "classDB", dbConfig);??
??????? classCatalog = new StoredClassCatalog(classDB);??
??? }??
??? // test: put key-value??
??? public void testPut(String key, Suppliers supp) throws Exception {??
??????? EntryBinding dataBinding = new SerialBinding(classCatalog,??
??????????????? Suppliers.class);??
??????? DatabaseEntry keyEntry = new DatabaseEntry(key.getBytes("UTF-8"));??
??????? DatabaseEntry dataEntry = new DatabaseEntry();??
??????? dataBinding.objectToEntry(supp, dataEntry);??
??????? db.put(null, keyEntry, dataEntry);??
??? }??
??? // test: get??
??? public void testGet() throws Exception {??
??????? EnvironmentConfig envConfig = new EnvironmentConfig();??
??????? envConfig.setAllowCreate(true);??
??????? // envConfig.setReadOnly(true);??
??????? env = new Environment(new File(".//src//util//importData"), envConfig);??
??????? List myDbNames = env.getDatabaseNames();??
??????? System.out.println("Database size: " + myDbNames.size());??
??????? for (int i = 0; i < myDbNames.size(); i++) {??
??????????? System.out.println("Database Name: " + (String) myDbNames.get(i));??
??????? }??
?
??????? DatabaseConfig dbConfig = new DatabaseConfig();??
??????? dbConfig.setAllowCreate(true);??
??????? // dbConfig.setReadOnly(true);??
??????? db = env.openDatabase(null, "myDB", dbConfig);??
??????? classDB = env.openDatabase(null, "classDB", dbConfig);??
??????? classCatalog = new StoredClassCatalog(classDB);??
?
??????? System.out.println("Db: " + db.count());??
?
??????? EntryBinding dataBinding = new SerialBinding(classCatalog,??
??????????????? Suppliers.class);??
?
??????? DatabaseEntry keyEntry = new DatabaseEntry("key".getBytes("UTF-8"));??
??????? DatabaseEntry dataEntry = new DatabaseEntry();??
??????? db.get(null, keyEntry, dataEntry, LockMode.DEFAULT);??
??????? Suppliers p = (Suppliers) dataBinding.entryToObject(dataEntry);??
??????? System.out.println(p.getCategory());??
??? }??
?
??? /**?
???? * test: read database?
???? * @throws Exception?
???? */?
??? public void testStore() throws Exception {??
?
??????? EnvironmentConfig envConfig = new EnvironmentConfig();??
??????? envConfig.setAllowCreate(true);??
??????? env = new Environment(new File(".//src//util//importData"), 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,Suppliers.class);??
?
??????? Cursor cursor = null;??
??????? CursorConfig config = new CursorConfig();??
??????? config.setDirtyRead(true);??
??????? cursor = db.openCursor(null, config);?????? // open cursor??
?
??????? try {??
??????????? // Database and environment open omitted for brevity??
??????????? // Open the cursor. cursor = myDatabase.openCursor(null, null);??
??????????? // Cursors need a pair of DatabaseEntry objects to operate. These hold??
??????????? // the key and data found at any given position in the database.??
??????????? DatabaseEntry foundKey = new DatabaseEntry();??
??????????? DatabaseEntry foundData = new DatabaseEntry();??
??????????? // To iterate, just call getNext() until the last database record has been??
??????????? // read. All cursor operations return an OperationStatus, so just read??
??????????? // until we no longer see OperationStatus.SUCCESS??
??????????? while (cursor.getNext(foundKey, foundData, LockMode.DEFAULT) == OperationStatus.SUCCESS) {??
??????????????? // getData() on the DatabaseEntry objects returns the byte array??
??????????????? // held by that object. We use this to get a String value. If the??
??????????????? // DatabaseEntry held a byte array representation of some other data??
??????????????? // type (such as a complex object) then this operation would look??
??????????????? // considerably different.??
??????????????? String keyString = new String(foundKey.getData());??
??????????????????
??????????????? Suppliers supp = (Suppliers)dataBinding.entryToObject(foundData);??
??????????????? System.out.println("Key - Data : " + keyString + " - "?
??????????????????????? + supp.getCompanyName() + "");??
??????????? }??
??????? } catch (DatabaseException de) {??
??????????? System.err.println("Error accessing database." + de);??
??????? } finally {??
??????????? // Cursors must be closed.??
??????????? cursor.close();??
??????????? db.close();??
??????????? classDB.close();??
??????????? env.cleanLog();??
??????????? env.close();??
??????? }??
?
??? }??
?
??? public void tearDown() throws Exception {??
??????? db.close();??
??????? classDB.close();??
??????? env.cleanLog();??
??????? env.close();??
??? }??
?
??? public static void main(String[] args) {??
??????? Jedtion t = new Jedtion();??
??????? try {??
??????????? // t.setUp();??
??????????? // Suppliers supp = new Suppliers();??
??????????? // supp.setCategory("fivefive");??
??????????? // t.testPut("5",supp);??
??????????? // t.testGet();??
??????????? // t.testStore();??
??????????????????????? // t.tearDown();??
??????? } catch (Exception e) {??
??????????? // TODO Auto-generated catch block??
??????????? e.printStackTrace();??
??????? }??
?
??? }??
}?

?