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. 16.2--Jenkins+Maven+Gitlab+Tomcat 自动化构建打包、部署

    分类: Linux服务篇,Linux架构篇   一.环境需求 本帖针对的是Linux环境,Windows或其他系统也可借鉴.具体只讲述Jenkins配置以及整个流程的实现. 1.JDK(或JRE)及J ...

  2. Windows CMD命令 查看无线密码

    netsh wlan show profiles netsh wlan show profiles name='无线网络名称' key=clear

  3. 第八篇:ORM框架SQLAlchemy 了解知识

    一 介绍 SQLAlchemy是Python编程语言下的一款ORM框架,该框架建立在数据库API之上,使用关系对象映射进行数据库操作,简言之便是:将对象转换成SQL,然后使用数据API执行SQL并获取 ...

  4. 科学计算库Numpy——数组形状

    改变数组维数 给数组的shape属性赋值,改变数组的维数.数组的大小是不能改变的. 增加维度 使用np.newaxis增加维度. 删除维度 使用squeeze()删除维度是1的维度,也就是删除shap ...

  5. Gym - 101981D Country Meow(模拟退火)

    题意 三维空间有\(n\)个点,找到另外一个点,离所有点的最大距离最小.求这个距离. 题解 \(1\).最小球覆盖,要找的点为球心. \(2\).模拟退火. 还是补一下模拟退火的介绍吧. 模拟退火有一 ...

  6. DiyCode开源项目 BaseActivity 分析

    1.首先将这个项目的BaseActivity源码拷贝过来. /* * Copyright 2017 GcsSloop * * Licensed under the Apache License, Ve ...

  7. #2 create and populate a database && realistic and practical applications (PART 2)

    Extends from the last chapter , This chapter takes a look at some real-world problems that can occur ...

  8. RDLC Reporting in Visual Studio 2017

    原文:RDLC Reporting in Visual Studio 2017 Visual Studio 2017 中可以使用 RDLC Reporting 插件来设计报表,SAP Crystal ...

  9. 图学java基础篇之集合工具

    两个工具类 java.utils下又两个集合相关_(准确来说其中一个是数组的)_的工具类:Arrays和Collections,其中提供了很多针对集合的操作,其中涵盖了一下几个方面: 拷贝.填充.反转 ...

  10. hdu3374 String Problem 最小最大表示法 最小循环节出现次数

    #include <iostream> #include <cstring> #include <cstdio> using namespace std; int ...