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。

下面是创建的过程:

  1. EnvironmentConfig envConfig = new EnvironmentConfig();
  2. envConfig.setAllowCreate(true);
  3. myDbEnvironment = new Environment(new File("/export/dbEnv"),
  4. envConfig);

其中EnvironmentConfig提供了许多配置参数,常用的有:

envConfig.setAllowCreate()//如果不存在的env的话,是否要创建一个新的

envConfig.setReadOnly()//是否为只读的

envConfig.setTransactional()//是否使用事务

参数都是boolean类型的

除了EnvironmentConfig外,还有EnvironmentMutableConfig,他实际是EnvironmentConfig的父类,使用他来配置在创建完Environment之后可以改变

的属性:

setCachePercent()//设置cache的大小占JVM memory的百分比

setCacheSize()//设置cache的大小

setTxnNoSync()//事务提交是否将改变的记录写入磁盘

setTxnWriteNoSync()//事务提交是否将log写入磁盘

下面看一下使用EnvironmentMutableConfig的方法:

  1. Environment myEnv = new Environment(new File("/export/dbEnv"), null);
  2. EnvironmentMutableConfig envMutableConfig =
  3. new EnvironmentMutableConfig();
  4. envMutableConfig.setTxnNoSync(true);
  5. myEnv.setMutableConfig(envMutableConfig);

Environment通过close来关闭,释放资源

下面看看Environment在管理方面的一些方法:

可以通过Environment获得EnvironmentStats,他提供了Environment一些状态信息,

例如使用

  1. long cacheMisses = myEnv.getStats(null).getNCacheMiss();

我们可以获得cache未命中的次数,据此来调整cache的大小

可以同过Environment.getDatabaseNames()来获得Environment的数据库的名字:

  1. List myDbNames = myDbEnv.getDatabaseNames();
  2. for(int i=0; i < myDbNames.size(); i++) {
  3. System.out.println("Database Name: " + (String)myDbNames.get(i));
  4. }

可以通过Environment.removeDatabase()来删除一个数据库:

  1. String dbName = myDB.getDatabaseName();
  2. myDB.close();
  3. myDBEnv.removeDatabase(null,dbName);

可以使用Environment.renameDatabase()来重新命名一个数据库:

  1. String dbName = myDB.getDatabaseName();
  2. String dbNewName = new String(dbName + ".new", "UTF-8");
  3. myDB.close();
  4. myDBEnv.renameDatabase(null,dbName,dbNewName);

可以使用Environment.truncateDatabase()来删除数据库中的所有记录:

  1. myEnv.truncate(null, // txn handle
  2. myDatabase.getDatabaseName(), // database name
  3. true//whether to return the count of deleted records
  4. );

第三个参数是否返回删除的记录数,性能有很大不同。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的使用流程:

  1. EnvironmentConfig envConfig = new EnvironmentConfig();
  2. envConfig.setAllowCreate(true);
  3. myDbEnvironment = new Environment(new File("/export/dbEnv"), envConfig);
  4. DatabaseConfig dbConfig = new DatabaseConfig();
  5. dbConfig.setAllowCreate(true);
  6. myDatabase = myDbEnvironment.openDatabase(null,
  7. "sampleDatabase",
  8. dbConfig);

我们通过Environment的openDatabase来创建Database对象。使用完了Database使用

close方法来关闭数据库释放资源。

Database Records

Database Record是保存在数据库的内容,包含Key和value两部分,他们都被封装成

DatabaseEntry,DatabaseEntry只能存放字节数组,所以只要能把Key和Value是什么

类型的,只要能转化成字节数组就可以被DatabaseEntry封装。基本类型JE都有对应的Binding,复杂的类型可以使用序列化和自定义binding来实现。

下那面我们看看一个使用方法:

  1. String aKey = "key";
  2. String aData = "data";
  3. try {
  4. DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
  5. DatabaseEntry theData = new DatabaseEntry(aData.getBytes("UTF-8"));
  6. } catch (Exception e) {
  7. }

我们不应该依赖机器默认的编码,通常要指定特定的编码方法getBytes("UTF-8");

我们先看看怎么从数据库中读写记录:

通过Database.put()和Database.get()我们可以从数据库中读写记录

put:

  1. String aKey = "myFirstKey";
  2. String aData = "myFirstData";
  3. try {
  4. DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
  5. DatabaseEntry theData = new DatabaseEntry(aData.getBytes("UTF-8"));
  6. myDatabase.put(null, theKey, theData);
  7. } catch (Exception e) {
  8. }

get:

  1. String aKey = "myFirstKey";
  2. try {
  3. DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
  4. DatabaseEntry theData = new DatabaseEntry();
  5. if (myDatabase.get(null, theKey, theData, LockMode.DEFAULT) ==
  6. OperationStatus.SUCCESS) {
  7. byte[] retData = theData.getData();
  8. String foundData = new String(retData, "UTF-8");
  9. System.out.println("For key: '" + aKey + "' found data: '" +
  10. foundData + "'.");
  11. } else {
  12. System.out.println("No record found for key '" + aKey + "'.");
  13. }
  14. } catch (Exception e) {
  15. }

删除操作:

  1. String aKey = "myFirstKey";
  2. DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
  3. 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);

下面代码以测试的形式演示了整个过程:

  1. package edu.jlu.fuliang;
  2. import java.io.File;
  3. import com.sleepycat.bind.EntryBinding;
  4. import com.sleepycat.bind.tuple.TupleBinding;
  5. import com.sleepycat.je.Database;
  6. import com.sleepycat.je.DatabaseConfig;
  7. import com.sleepycat.je.DatabaseEntry;
  8. import com.sleepycat.je.Environment;
  9. import com.sleepycat.je.EnvironmentConfig;
  10. import com.sleepycat.je.LockMode;
  11. import junit.framework.TestCase;
  12. public class PrimitiveBindingTest extends TestCase{
  13. private Environment env;
  14. private Database db;
  15. private String key = "akey";
  16. private Long data = 1234556633L;
  17. public void setUp()throws Exception{
  18. EnvironmentConfig envConfig = new EnvironmentConfig();
  19. envConfig.setAllowCreate(true);
  20. env = new Environment(new File("etc/dbEnv"),envConfig);
  21. DatabaseConfig dbConfig = new DatabaseConfig();
  22. dbConfig.setAllowCreate(true);
  23. db = env.openDatabase(null, "myDB", dbConfig);
  24. DatabaseEntry keyEntry = new DatabaseEntry(key.getBytes("UTF-8"));
  25. DatabaseEntry dataEntry = new DatabaseEntry();
  26. EntryBinding myBinding = TupleBinding.getPrimitiveBinding(Long.class);
  27. myBinding.objectToEntry(data, dataEntry);
  28. db.put(null, keyEntry, dataEntry);
  29. }
  30. public void testGet()throws Exception{
  31. DatabaseEntry keyEntry = new DatabaseEntry(key.getBytes("UTF-8"));
  32. DatabaseEntry dataEntry = new DatabaseEntry();
  33. EntryBinding binding = TupleBinding.getPrimitiveBinding(Long.class);
  34. db.get(null, keyEntry, dataEntry, LockMode.DEFAULT);
  35. Long l = (Long)binding.entryToObject(dataEntry);
  36. assertEquals(l,data);
  37. }
  38. public void tearDown()throws Exception{
  39. db.close();
  40. env.truncateDatabase(null, "myDB",false);
  41. env.close();
  42. }
  43. }

序列化复杂的类型

步骤如下:

1、要存储的对象的类需要实现java.io.Serializable

2、打开两个数据库,一个存放数据,另一个存放类的信息

3、实例化com.sleepycat.bind.serial.StoredClassCatalog对象

4、创建uses com.sleepycat.bind.serial.SerialBinding对象

5、使用SerialBinding把对象放到DatabaseEntry中

下面是使用一个能够完整描述这个过程的例子来说明这个过程:

  1. package edu.jlu.fuliang;
  2. import java.io.File;
  3. import com.sleepycat.bind.EntryBinding;
  4. import com.sleepycat.bind.serial.SerialBinding;
  5. import com.sleepycat.bind.serial.StoredClassCatalog;
  6. import com.sleepycat.je.Database;
  7. import com.sleepycat.je.DatabaseConfig;
  8. import com.sleepycat.je.DatabaseEntry;
  9. import com.sleepycat.je.DatabaseException;
  10. import com.sleepycat.je.Environment;
  11. import com.sleepycat.je.EnvironmentConfig;
  12. import com.sleepycat.je.LockMode;
  13. import junit.framework.TestCase;
  14. public class SerializableTypeTest extends TestCase{
  15. private Person person;
  16. private Environment env;
  17. private Database db,classDB;
  18. private StoredClassCatalog classCatalog;
  19. public void setUp()throws Exception{
  20. person = new Person();
  21. person.setAge(12);
  22. person.setName("zhansan");
  23. person.setSex('m');
  24. EnvironmentConfig envConfig = new EnvironmentConfig();
  25. envConfig.setAllowCreate(true);
  26. env = new Environment(new File("etc/dbEnv"),envConfig);
  27. DatabaseConfig dbConfig = new DatabaseConfig();
  28. dbConfig.setAllowCreate(true);
  29. db = env.openDatabase(null, "myDB", dbConfig);
  30. classDB = env.openDatabase(null, "classDB", dbConfig);
  31. classCatalog = new StoredClassCatalog(classDB);
  32. EntryBinding dataBinding = new SerialBinding(classCatalog,Person.class);
  33. DatabaseEntry keyEntry = new DatabaseEntry(person.getName().getBytes("UTF-8"));
  34. DatabaseEntry dataEntry = new DatabaseEntry();
  35. dataBinding.objectToEntry(person, dataEntry);
  36. db.put(null, keyEntry, dataEntry);
  37. }
  38. public void testGet()throws Exception{
  39. EntryBinding dataBinding = new SerialBinding(classCatalog,Person.class);
  40. DatabaseEntry keyEntry = new DatabaseEntry(person.getName().getBytes("UTF-8"));
  41. DatabaseEntry dataEntry = new DatabaseEntry();
  42. db.get(null, keyEntry, dataEntry, LockMode.DEFAULT);
  43. Person p = (Person)dataBinding.entryToObject(dataEntry);
  44. assertEquals(p.getName(),person.getName());
  45. assertEquals(p.getAge(),person.getAge());
  46. assertEquals(p.getSex(), person.getSex());
  47. }
  48. public void tearDown()throws Exception{
  49. db.close();
  50. classDB.close();
  51. env.truncateDatabase(null, "myDB", false);
  52. env.truncateDatabase(null, "classDB", false);
  53. env.close();
  54. }
  55. }

要存储的对象对应的类

  1. package edu.jlu.fuliang;
  2. import java.io.Serializable;
  3. public class Person implements Serializable{
  4. private String name;
  5. private int age;
  6. private char sex;
  7. public int getAge() {
  8. return age;
  9. }
  10. public void setAge(int age) {
  11. this.age = age;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19. public char getSex() {
  20. return sex;
  21. }
  22. public void setSex(char sex) {
  23. this.sex = sex;
  24. }
  25. }

自定义元组绑定:

存储复杂对象自定义元组绑定的步骤:

1、创建要存储的对象,这个对象的类没有必要实现Serializable接口:

2、扩展com.sleepycat.bind.tuple.TupleBinding来实现自定义的Binging

3、创建2步欻关键的自定义binding对象

4、将创建的对象是用自定义个binding放到DatabaseEntry中

5、使用put方法存入数据库

下面的例子说明了这个过程:

自定义Binging:

  1. package edu.jlu.fuliang;
  2. import com.sleepycat.bind.tuple.TupleBinding;
  3. import com.sleepycat.bind.tuple.TupleInput;
  4. import com.sleepycat.bind.tuple.TupleOutput;
  5. public class PersonTupleBinding extends TupleBinding{
  6. @Override
  7. public Object entryToObject(TupleInput ti) {
  8. Person person = new Person();
  9. person.setName(ti.readString());
  10. person.setAge(ti.readInt());
  11. person.setSex(ti.readChar());
  12. return person;
  13. }
  14. @Override
  15. public void objectToEntry(Object obj, TupleOutput output) {
  16. Person person = (Person)obj;
  17. output.writeString(person.getName());
  18. output.writeInt(person.getAge());
  19. output.writeChar(person.getSex());
  20. }
  21. }

put/get的使用过程:

    1. package edu.jlu.fuliang;
    2. import java.io.File;
    3. import com.sleepycat.je.Database;
    4. import com.sleepycat.je.DatabaseConfig;
    5. import com.sleepycat.je.DatabaseEntry;
    6. import com.sleepycat.je.DatabaseException;
    7. import com.sleepycat.je.Environment;
    8. import com.sleepycat.je.EnvironmentConfig;
    9. import com.sleepycat.je.LockMode;
    10. import junit.framework.TestCase;
    11. public class CustomTupleBindingTest extends TestCase{
    12. private Person person;
    13. private Environment env;
    14. private Database db;
    15. public void setUp()throws Exception{
    16. person = new Person();
    17. person.setAge(12);
    18. person.setName("zhansan");
    19. person.setSex('m');
    20. EnvironmentConfig envConfig = new EnvironmentConfig();
    21. envConfig.setAllowCreate(true);
    22. env = new Environment(new File("etc/dbEnv"),envConfig);
    23. DatabaseConfig dbConfig = new DatabaseConfig();
    24. dbConfig.setAllowCreate(true);
    25. db = env.openDatabase(null, "myDB", dbConfig);
    26. PersonTupleBinding binding = new PersonTupleBinding();
    27. DatabaseEntry keyEntry = new DatabaseEntry(person.getName().getBytes("UTF-8"));
    28. DatabaseEntry dataEntry = new DatabaseEntry();
    29. binding.objectToEntry(person, dataEntry);
    30. db.put(null, keyEntry, dataEntry);
    31. }
    32. public void testGet()throws Exception{
    33. PersonTupleBinding binding = new PersonTupleBinding();
    34. DatabaseEntry keyEntry = new DatabaseEntry(person.getName().getBytes("UTF-8"));
    35. DatabaseEntry dataEntry = new DatabaseEntry();
    36. db.get(null, keyEntry, dataEntry, LockMode.DEFAULT);
    37. Person p = (Person)binding.entryToObject(dataEntry);
    38. assertEquals(p.getName(),person.getName());
    39. assertEquals(p.getAge(),person.getAge());
    40. assertEquals(p.getSex(), person.getSex());
    41. }
    42. public void tearDown()throws Exception{
    43. db.close();
    44. env.truncateDatabase(null, "myDB", false);
    45. env.close();
    46. }
    47. }

Berkely DB Java Edition学习笔记的更多相关文章

  1. 尚学堂JAVA基础学习笔记

    目录 尚学堂JAVA基础学习笔记 写在前面 第1章 JAVA入门 第2章 数据类型和运算符 第3章 控制语句 第4章 Java面向对象基础 1. 面向对象基础 2. 面向对象的内存分析 3. 构造方法 ...

  2. 20145213《Java程序设计学习笔记》第六周学习总结

    20145213<Java程序设计学习笔记>第六周学习总结 说在前面的话 上篇博客中娄老师指出我因为数据结构基础薄弱,才导致对第九章内容浅尝遏止地认知.在这里我还要自我批评一下,其实我事后 ...

  3. [原创]java WEB学习笔记95:Hibernate 目录

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  4. java JDK8 学习笔记——助教学习博客汇总

    java JDK8 学习笔记——助教学习博客汇总 1-6章 (by肖昱) Java学习笔记第一章——Java平台概论 Java学习笔记第二章——从JDK到IDEJava学习笔记第三章——基础语法Jav ...

  5. java JDK8 学习笔记——第16章 整合数据库

    第十六章 整合数据库 16.1 JDBC入门 16.1.1 JDBC简介 1.JDBC是java联机数据库的标准规范.它定义了一组标准类与接口,标准API中的接口会有数据库厂商操作,称为JDBC驱动程 ...

  6. [原创]java WEB学习笔记75:Struts2 学习之路-- 总结 和 目录

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  7. [原创]java WEB学习笔记66:Struts2 学习之路--Struts的CRUD操作( 查看 / 删除/ 添加) 使用 paramsPrepareParamsStack 重构代码 ,PrepareInterceptor拦截器,paramsPrepareParamsStack 拦截器栈

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  8. Android(java)学习笔记267:Android线程池形态

    1. 线程池简介  多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.     假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...

  9. java多线程学习笔记——详细

    一.线程类  1.新建状态(New):新创建了一个线程对象.        2.就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法.该状态的线程位于可运行线程池中, ...

随机推荐

  1. IDEA整合Mybatis+Struts2+Spring (二)--整合框架

    二.搭建目录结构 我这里列出的是搭建完了之后所有的目录和文件,诸位先把目录文件建起来,然后我在给出文件内容 这里的目录建好之后还需要设置一下,让idea识别目录作用,选择File-Project St ...

  2. 四 python并发编程之协程

    一 引子 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两种情况下切走去 ...

  3. js跨域及解决办法

    1.什么是跨域 我们经常会在页面上使用ajax请求访问其他服务器的数据,此时,客户端会出现跨域问题. 跨域问题是由于javascript语言安全限制中的同源策略造成的. 简单来说,同源策略是指一段脚本 ...

  4. LeetCode#5 两个排序数组的中位数

      给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 . 请找出这两个有序数组的中位数.要求算法的时间复杂度为 O(log (m+n)) . 你可以假设 nums1 和 nums2  ...

  5. JZOJ 4757. 树上摩托

    Description Sherco是一位经验丰富的魔♂法师.Sherco在第零次圣杯战争中取得了胜利,并取得了王之宝藏——王の树.他想把这棵树砍去任意条边,拆成若干棵新树,并装饰在他的摩托上,让他的 ...

  6. selenium中webdriver跳转新页面后定位置新页面的两种方式

    刚刚在写Python爬虫的时候用到了selenium , 在跳转新页面时发现无法定位新页面 , 查找不到新页面的元素 一番查询后得到了解决方法 , 便记录下来备忘 , 也与大家分享 # 页面跳转代码. ...

  7. Python学习笔记(七)加密加盐

    MD5加密和加盐 Python的MD5加密 Python的hashlib模块的MD5加密,是比较简单一种加密,md5函数必须传入编译后的结果,否则会报错: Traceback (most recent ...

  8. python3+openCV实现图片的人脸人眼检测,原理+参数+源代码

    上学时候用matlab学过一些图像处理的基础知识,当时课程作业是用haar实现人脸检测 but当时是心思根本不在图像处理上,so找了个同学帮忙做的,自己没上心 然鹅天道好轮回,现在捡起来了原来的算法一 ...

  9. libevent源码分析1 ----evnet相关结构体分析

    位于代码event-internal.h中. event_base类似事件的集合,你创建一个事件,必须将该事件指定一个集合. struct event_base { 50     const stru ...

  10. 大数运算:HDU-1042-N!(附N!位数的计算)

    解题心得: 这里使用了10000进制.很明显,因为是n!所以单个最大的数是10000*10000,使用万进制. 可以借鉴高精度的加法,单个乘了之后在进位. 很坑的一点,0!=1,数学不好WA了三次,尴 ...