用户操作
[即时聊天] [发私信] [加为好友]
Java and OpenSource Engine
Java and OpenSource Engine的公告
拒绝浮躁,历练人生
最近评论
xiaonan_712:恩~有道理~记下了
雨夜:在tomcat里配置web.xml之后
总是报系统找不到jcrontab.properties文件.
这是怎么回事?
路人甲:说的一针见血
hehe:呵呵!!但是对阁下这点有不同意见:
(1) 精通一门编程工具,不要什么东西都想学,什么都没掌握。

现在东西变得快!!一会Delphi,一会.Net,会Java
不是我想学,只是那些招聘要求上写的这些都要会
baiyj:谢谢各位啦!呵呵
文章分类
收藏
相册
Beautiful Picture
Programming
Ajax
Ajax专题
Ajax中国
DWR
Echo
Echo Demo
ExtJS
EXT中文站
HelloAjax
prototype
Prototype Window
script.aculo.us
Spry framework for Ajax
Wikipedia-Ajax
CSS
Css Zen Garden
meyerWeb
Database
Hsqldb数据库
Debug Tools
ANT安装、配置
Ant官方网站
Apache Ant 1.7.0 Manual
Canoo WebTest
DbUnit
Development IDE
IntelliJ IDEA使用技巧一览表
IntelliJ IDEA官方下载
Jedit官方网站
Netbean官方网站
yahoo small business
Eclipse
Eclipse Downloads
Eclipse Plugins
Eclipse赛迪网
Log4e
MyEclipse官方网站
WTP Project
XMLBuddy™ Pro 2.0.11
中国Eclipse社区
Famous Site
Apache Jakarta Project
CSDN.NET
Dashboard
DingL.com
Huihoo
IBM Developerworks
Java Enterprise Projects
Java Research
Java2.5341
Javaeye
JavaSight
JavaWorld
Java研究组织-研究文集
J道-专业的设计研究网站
SourceForge.net
SpringSide
SUN技术社区
TheServerSide
GUI
Cloud Garden
Getting Started with Eclipse and the SWT
Java图形界面开发:SWT全接触
SWT Snippets
SWT-Designer
Hibernate
hibernate annotations en
hibernate annotations zh
Hibernate中文网
Hibernate主站点
国外开源hibernate研究
Java
java中文站
Java视线论坛
Java频道-中国IT实验室
JDocs
Matrix-与Java共舞
JavaScript
BlueShoes
Dynamicdrive
TinyMCE中文手册
JPA
JPA注解指南
JPA重整ORM山河
常用 JPA annotation 参考
Log4j
log4j简单使用说明
竹笋炒肉-Log4J学习笔记2
竹笋炒肉-Log4J学习笔记3
竹笋炒肉-log4j学习笔迹1
Lucene
Advanced Text Indexing with Lucene
Apache Jakarta Lucene
Lucene Intro
Luke Tool
QueryParser Rules
全文索引引擎Lucene简介
My Friends Blog
DXJ Boke
WL Boke
阿水
My Other Site
My Host
文渊阁
Nutch
Nutch简介
SourceForge.net Nutch
国外Nutch研究
OpenSource
Alexa Web Search
Apache JSTL
Autometa devOpen
Berkeley DB 概述
Cocoon
Commons Configuration
Commons Digester
Compass
Display Tag
Heritrix
Jaction Group.net
JavaSource
Java开源大全
Jcrontab官方网站
Jfree
jtds
Netarchive.dk to ARC
Proxool
redsaga-confluence
Sourceforge.net Of Jcrontab
SysTray for Java
The I18N Taglibs
Torque
Tray Icon API
WebWork Framework
web应用架构(struts+spring+hibernate)讲解
Zilverline Search Engine
Other Software
Codehaus
JavaMail全面解析
Java电子书专题下载
开源网站DEVX
开源网站ObjectWeb
开源网站Opensymphony
Others Blog
!java
baggio785的专栏
Icebird
LHWork Blog
Max On Java
Mstar
mulder的程序人生
wojiaoliufeng的专栏
一地鸡毛
上善若水的程序人生
冰雨Blog
花钱的年华
落叶无痕
行云与流水
车东 Che, Dong
Project Manage
项目管理者联盟
Reports
BO产品线
Business Objects中文官方网站
Business Objects官方网站
Report99.com
对数据仓库进行数据建模
数据仓库之路
Ruby
GEM Download
IinstantRails
railscn
RubyEclipse
RubyTao
动态感觉静观其变
道喜技术日记
Spring
Acegi
Spring AOP APIs
Spring Aop Step-By-Step
Spring Downloads
Spring 框架简介
SpringFramework中文论坛
Spring资源
国外Spring官方论坛
Struts2
Easy Struts Plugin
Struts Console
Struts2技术学习专题
The Apache Struts
UML
ArgoUML
OOChina
UMLChina
UML软件工程组织
Web Server
WebSphere Application Server for iSeries 信息中心
Windows下的修改Tomcat的可用内存
Web Service
WebServiceX
使用 WSDL 部署 Web 服务: 第 1 部分
WEB2.0
DODO
Pownce
Thinkature
Twitter
交互组件演示
抓虾
存档
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
订阅到BlogLines
订阅到Yahoo
订阅到GouGou
订阅到飞鸽
订阅到Rojo
订阅到newsgator
订阅到netvibes

原创 Berkeley DB Research 收藏

新一篇: Hibernate的简单应用 | 旧一篇: JDK中的几个有用的类

Berkeley DB Java Edition Research
 


一、Berkeley DB Java Edition简介
  1. Berkeley DB JE is a general-purpose, transactionally protected, embedded database written in 100% Java (JE makes no JNI calls). As such, it offers the Java developer safe and efficient in-process storage and management of arbitrary data.
  2. Berkeley DB的特点:
    • 数据存储能力很强(Large database support)
    • 支持多线程(Multiple thread and process support)
    • 数据库的记录很简单,只是简单的键值对(Database records)
    • 提供事务支持(Transactions)
    • 提供索引支持(Indexes)
    • 提供内存缓存的支持(In-memory cache)
    • 按照连续的记录文件存储数据(Log files)
    • 后台线程的支持(Background threads)
    • 数据库环境封装了一个或多个数据库(Database environments)
    • 支持数据库的备份和恢复(Backup and restore)
  3. 下载Berkeley DB Java Edition:可以从http://www.sleepycat.com/download/index.shtml网址下载
  4. 安装Berkeley DB Java Edition:将下载的文件解压后放到JE_HOME下面。
  5. 使用Berkeley DB,应用程序使用时,需要配置je.jar包,要将JE_HOME/lib/je.jar 加到你的应用程序中
  6. Berkeley DB Exception主要有三个异常:DatabaseNotFoundException,DeadlockException,RunRecoveryException

二、Berkeley DB Java Edition的使用及举例说明

      根据Berkeley DB的文档介绍,在这里简单的介绍一下用Berkeley DB开发的步骤:

  1. 构建数据库的开发环境
    用Berkeley DB Java Edition开发数据库时,需要构建数据库的开发环境。Berkeley DB主要是在这个环境下工作的,并且处理数据库也是在这个环境下工作的。
    import com.sleepycat.je.Environment;
    import com.sleepycat.je.DatabaseException;
    import com.sleepycat.je.EnvironmentConfig;
    import java.io.File;
    ......
    Environment myDbEnvironment = null;
    try {
        EnvironmentConfig envConfig = new EnvironmentConfig();
        envConfig.setAllowCreate(true);
    /**这里的"/export/dbEnv"就是指定的数据库开发环境的目录*/
        myDbEnvironment = new Environment(new File("/export/dbEnv"), envConfig);
    } catch (DatabaseException dbe) {
        // Exception handling goes here
    }

    在这里对环境的属性可以进行设置,当然也可以通过配置文件je.properties来得到。
    像上例中的"envConfig.setAllowCreate(true);"这个设置就是说,当设置为true时,说明若没有数据库的环境时,可以打开。否则就不能打开。其它的属性,可以查看有关Berkeley DB Java Edition文档。
    程序运行完了,一般要关闭数据库的环境的,这就需要调用myDbEnvironment.close()方法来执行,释放系统资源。
  2. 构建数据库
    数据库的构造是在数据库环境的基础上构建的,这里还需要数据库属性的配置,不同的数据库可以配置不同的属性设置。
    例:
    import com.sleepycat.je.DatabaseException;
    import com.sleepycat.je.Database;
    import com.sleepycat.je.DatabaseConfig;
    import com.sleepycat.je.Environment;
    import com.sleepycat.je.EnvironmentConfig;
    import java.io.File;
    ......
    Environment myDbEnvironment = null;
    Database myDatabase = null;
    ......
    try {
        // Open the environment. Create it if it does not already exist.
        EnvironmentConfig envConfig = new EnvironmentConfig();
        envConfig.setAllowCreate(true);
        myDbEnvironment = new Environment(new File("/export/dbEnv"), envConfig);
    
        // Open the database. Create it if it does not already exist.
        DatabaseConfig dbConfig = new DatabaseConfig();
        dbConfig.setAllowCreate(true);
        myDatabase = myDbEnvironment.openDatabase(null, 
                                                  "sampleDatabase", 
                                                  dbConfig); 
    } catch (DatabaseException dbe) {
        // Exception handling goes here
    }

    从这里的例子可以看出数据库myDatabase需要DatabaseConfig的配置,一般数据库的属性的配置需要它在这里的配置,然后数据库myDatabase才可以得到。如:myDatabase = myDbEnvironment.openDatabase(null,"sampleDatabase",dbConfig);
    这里的“dbConfig.setAllowCreate(true);”就是设置数据的是否可以创建的属性,这里是可以创建的。有关数据库配置的其它属性,可以查看有关的文档。
    释放数据库资源一般用Database.close()来操作。
  3. 使用数据库的字段
    Berkeley DB中的记录包括两个字段,就是键和值,并且这些键和值都必须是com.sleepycat.je.DatabaseEntry类的实例。
    import com.sleepycat.je.DatabaseEntry;
    ......
    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) {
        // Exception handling goes here
    }

    在这里可以看到,我们用的是UTF-8的编码,其实,也可以使用其它的编码。对于存储和得到数据都不会产生任何影响。
    当得到从数据库中得到数据时,因为它都是按照字节存储的,所以,我们取出数据时,需要转换一下。
    import com.sleepycat.je.DatabaseEntry;
    ......
    byte[] myKey = theKey.getData();
    byte[] myData = theData.getData();
    String key = new String(myKey);
    String data = new String(myData);
    ......
    这样就可以按照Java中的String类,来取出数据了。
  4. 对数据库的各种操作具有了数据库对象之后,就可以根据这个数据库对象来执行具体的数据库操作,包括插入,检索,删除的操作。
    在Berkeley DB中默认是不支持重复记录的,若有重复的记录集的话,也可以使用游标来完成操作。
    • 从数据库中插入数据:这里提供了三种方法,put(),putNoOverwrite(),putNoDupData(),它们的主要区别还是在于插入的记录是否有重复,根据重复记录来判断这些操作,多数情况下,使用put()方法来操作插入。
      import com.sleepycat.je.DatabaseEntry;
      import com.sleepycat.je.Database;
      .....
      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) {
          // Exception handling goes here
      }
    • 从数据库中取得数据,一般使用get()方法得到指定关键字的记录,getSearchBoth()这个方法是根据所匹配的关键字来得到所需要的记录。
      import com.sleepycat.je.DatabaseEntry;
      import com.sleepycat.je.Database;
      import com.sleepycat.je.LockMode;
      import com.sleepycat.je.OperationStatus;
      .....
      // Environment and database opens omitted for clarity.
      // Environment and database may be opened read-only.  
        
      String aKey = "myFirstKey";
      try {
          // Create a pair of DatabaseEntry objects. theKey
          // is used to perform the search. theData is used
          // to store the data returned by the get() operation.
          DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
          DatabaseEntry theData = new DatabaseEntry();
          
          // Perform the get.
          if (myDatabase.get(null, theKey, theData, LockMode.DEFAULT) ==
              OperationStatus.SUCCESS) {
      
              // Recreate the data String.
              byte[] retData = theData.getData();
              String foundData = new String(retData);
              System.out.println("For key: '" + aKey + "' found data: '" + 
                                  foundData + "'.");
          } else {
              System.out.println("No record found for key '" + aKey + "'.");
          } 
      } catch (Exception e) {
          // Exception handling goes here
      }
    • 删除数据库中的记录,一般是用Database.delete()方法,若数据库中存在重复的记录,要删除掉具有重复的关键字的记录的话,就会将所有具有该关键字的记录都删除掉了。也就是删除掉了一个记录的集合。
      import com.sleepycat.je.DatabaseEntry;
      import com.sleepycat.je.Database;
      .....
      // Environment and database opens omitted for clarity.
      // Environment and database can NOT be opened read-only.  
      try {
          String aKey = "myFirstKey";
          DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));
          
          // Perform the deletion. All records that use this key are
          // deleted.
          myDatabase.delete(null, theKey); 
      } catch (Exception e) {
          // Exception handling goes here
      }

      这里是根据指定的关键字"myFirstKey",来删除掉指定的记录,若该记录有重复的话,那么就会删掉该关键字的所有的记录集合。
  5. 游标的操作
    游标的各种操作和数据库的各种操作都差不多。方法大体上是一样的。
    • 游标的建立和关闭
      游标也是建立在数据库基础之上的,因此,游标需要得到数据库的对象。
      import com.sleepycat.je.Environment;
      import com.sleepycat.je.Database;
      import com.sleepycat.je.DatabaseException;
      import com.sleepycat.je.Environment;
      import com.sleepycat.je.CursorConfig;
      import com.sleepycat.je.Cursor;
      import java.io.File;
      ......
      Environment myDbEnvironment = null;
      Database myDatabase = null;
      Cursor myCursor = null;
      try {
          myDbEnvironment = new Environment(new File("/export/dbEnv"), null);
          myDatabase = myDbEnvironment.openDatabase(null, "myDB", null);
      
          myCursor = myDatabase.openCursor(null, null);
      } catch (DatabaseException dbe) {
          // Exception handling goes here ...
      }
      从这里可以看到游标是建立在数据库基础之上的。
      游标的关闭直接调用cursor.close()方法就可以了。
    • 用游标插入数据到数据库
      这里也是采用的put(),putNoDupData(),putNoOverwrite()三个方法来实现的,它们的使用方法和数据库的插入方法一样,这几个方法的区别也是在于对重复记录的判断上,具体的区别请看有关的资料。
      import com.sleepycat.je.DatabaseEntry;
      import com.sleepycat.je.Database;
      import com.sleepycat.je.Cursor;
      import com.sleepycat.je.OperationStatus; 
      .....
      // Create the data to put into the database
      String key1str = "My first string";
      String data1str = "My first data";
      String key2str = "My second string";
      String data2str = "My second data";
      String data3str = "My third data";
      Cursor cursor = null;
      try {
          ...
          // Database and environment open omitted for brevity
          ...
      
          DatabaseEntry key1 = new DatabaseEntry(key1str.getBytes("UTF-8"));
          DatabaseEntry data1 = new DatabaseEntry(data1str.getBytes("UTF-8"));
          DatabaseEntry key2 = new DatabaseEntry(key2str.getBytes("UTF-8"));
          DatabaseEntry data2 = new DatabaseEntry(data2str.getBytes("UTF-8"));
          DatabaseEntry data3 = new DatabaseEntry(data3str.getBytes("UTF-8"));
      
          // Open a cursor using a database handle
          cursor = myDatabase.openCursor(null, null);
      
          // Assuming an empty database.
      
          OperationStatus retVal = cursor.put(key1, data1); // SUCCESS
          retVal = cursor.put(key2, data2); // SUCCESS
          retVal = cursor.put(key2, data3); // SUCCESS if dups allowed, 
                                            // KEYEXIST if not.    
                                                    
      } catch (Exception e) {
          // Exception handling goes here
      } finally {
         // Make sure to close the cursor
         cursor.close();
      }
      在这个例子中,可以看到一开始的时候,cursor.put(key2, data2)执行后,在数据库中就已经有了key2的记录,后来,要调用了cursor.put(key2, data3)方法后,由于在数据库中已经存在了一个key2的记录,现在又在这个key2基础上添加一个,若允许数据库是重复的,因此这里就替代掉了原来的data2的数据了,现在是data3了。
    • 用游标来得到数据和检索数据
      使用游标最大的优点还是在于能够很方便的检索记录。用游标得到记录可以用getNext(),getPrev()等方法。
      import com.sleepycat.je.DatabaseEntry;
      import com.sleepycat.je.Database;
      import com.sleepycat.je.DatabaseException;
      import com.sleepycat.je.Cursor;
      import com.sleepycat.je.OperationStatus; 
      import com.sleepycat.je.LockMode;  
      .....
      Cursor cursor = null;
      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());
              String dataString = new String(foundData.getData());
              System.out.println("Key - Data : " + keyString + " - " + dataString + "");
          }
      } catch (DatabaseException de) {
          System.err.println("Error accessing database." + de);
      } finally {
          // Cursors must be closed.
          cursor.close();
      }
      在这里例子实际上就是遍历数据库所有的记录,将它打印出来,也可以使用getPrev()方法,也可以实现遍历数据库的操作。在重复的记录中,用数据库就无法操作,用游标就可以实现对重复记录的访问,也是使用这几个方法。
      检索关键字是使用游标的getSearchKey(),getSearchKeyRange(),getSearchBoth(),getSearchBothRange()方法,这些方法的区别在于匹配的操作,具体的区别请参考有关的资料。
      import com.sleepycat.je.DatabaseEntry;
      import com.sleepycat.je.Database;
      import com.sleepycat.je.DatabaseException;
      import com.sleepycat.je.Cursor;
      import com.sleepycat.je.OperationStatus; 
      import com.sleepycat.je.LockMode;
      .....
      // For this example, hard code the search key and data
      String searchKey = "Al";
      String searchData = "Fa";
      
      Cursor cursor = null;
      try {
          ...
          // Database and environment open omitted for brevity
          ...
      
          // Open the cursor. 
          cursor = myDatabase.openCursor(null, null);
      
          DatabaseEntry theKey = 
               new DatabaseEntry(searchKey.getBytes("UTF-8"));
          DatabaseEntry theData = 
               new DatabaseEntry(searchData.getBytes("UTF-8"));
      
          // Open a cursor using a database handle
          cursor = myDatabase.openCursor(null, null);
      
          // Perform the search
          OperationStatus retVal = cursor.getSearchBothRange(theKey, theData, 
                                                             LockMode.DEFAULT);
          // NOTFOUND is returned if a record cannot be found whose key begins 
          // with the search key AND whose data begins with the search data.
          if (retVal == OperationStatus.NOTFOUND) {
              System.out.println(searchKey + "/" + searchData + 
                                 " not matched in database " + 
                                 myDatabase.getDatabaseName());
          } else {
              // Upon completing a search, the key and data DatabaseEntry 
              // parameters for getSearchBothRange() are populated with the 
              // key/data values of the found record.
              String foundKey = new String(theKey.getData());
              String foundData = new String(theData.getData());
              System.out.println("Found record " + foundKey + "/" + foundData + 
                                 "for search key/data: " + searchKey + 
                                 "/" + searchData);
          }
      
      } catch (Exception e) {
          // Exception handling goes here
      } finally {
         // Make sure to close the cursor
         cursor.close();
      }
      这个例子,用的是getSearchBothRange()方法,它主要是用来查询匹配这个关键字和该关键字的数据的所有记录。 Cursor.count()这个方法,是用来统计当前键的出现的总的记录数。
    • 用游标删除数据库中的数据,用cursor.delete()方法,和数据库中的delete()方法用法一样。不在举例说明了。
    • 使用游标来代替当前键的值,用cursor.putCurrent()方法来实现,这在数据库中的操作方法中是很难实现的,用游标的这个方法,可以很方便的实现该操作。
      import com.sleepycat.je.DatabaseEntry;
      import com.sleepycat.je.Database;
      import com.sleepycat.je.DatabaseEntry;
      import com.sleepycat.je.Cursor;
      import com.sleepycat.je.OperationStatus; 
      import com.sleepycat.je.LockMode;
      ......
      Cursor cursor = null;
      try {
          ...
          // Database and environment open omitted for brevity
          ...
          // Create DatabaseEntry objects
          // searchKey is some String.
          DatabaseEntry theKey = new DatabaseEntry(searchKey.getBytes("UTF-8"));
          DatabaseEntry theData = new DatabaseEntry();
      
          // Open a cursor using a database handle
          cursor = myDatabase.openCursor(null, null);
      
          // Position the cursor. Ignoring the return value for clarity
          OperationStatus retVal = cursor.getSearchKey(theKey, theData, 
                                                      LockMode.DEFAULT);
          
          // Replacement data
          String replaceStr = "My replacement string";
          DatabaseEntry replacementData = 
              new DatabaseEntry(replaceStr.getBytes("UTF-8"));
          cursor.putCurrent(replacementData);
      } catch (Exception e) {
          // Exception handling goes here
      } finally {
         // Make sure to close the cursor
         cursor.close();
      }
      这里的操作是用来代替掉指定的关键字的值,但是若有重复记录的话,就无法实现了。
  6. 事务的处理
    Berkeley DB Java Edition提供了全部的事务的ACID的所有属性。(Atomicity,Consistency,Isolation,Durability)。
    在Berkeley DB中使用事务时,可以很方便的配置和使用:
    • 需要在数据库环境中配置事务的操作为可用的,EnvironmentConfig.setTransactional(true),这样就设置好了数据库环境下可以方便的使用事务。
    • 在数据库中也要设置事务为可用的,DatabaseConfig.setTransactional(true),这样数据库就设置好了事务的处理。
    • 接下来就可以在程序中使用事务了,在需要的地方插入transaction.commit(),提交事务。
  7. 数据备份和恢复
    • 数据的备份分为两种:一种是部分备份,另一种是全部备份。它们的共同点就是拷贝所有的log files(.jdb)文件从数据库的环境目录到所要归档的目录或备份媒体。在这之前,必须要关闭事务,若存在事务,就无法它们的区别就是:部分备份是从最后一次备份开始到凡是修改过的或新增加的记录都需要备份,而全部备份是将所有的数据库信息,包括内存缓存中的数据都要备份,不过这需要停止写操作。
    • 数据的恢复:简单的说就是将备份的log files文件拷贝到数据库的环境目录下,这里可以是增量备份,也可以是全部的备份,一般都是增量恢复,这些操作必须要关闭JE的应用程序。
  8. 其它
    在这里只是说一下je.properties文件,这个文件是用来提供配置Berkeley DB的后台以及整体系统运行的参数,有的参数在je.properties文件中可以设置,在程序中也可以设置,但是在这个文件里的参数优先于程序中设置的参数。这个文件必须放在数据库环境的根目录下,这样系统才能执行该文件中的参数。

发表于 @ 2004年09月29日 17:46:00|评论(loading...)|编辑

新一篇: Hibernate的简单应用 | 旧一篇: JDK中的几个有用的类

评论:没有评论。

发表评论  


登录
Csdn Blog version 3.1a
Copyright © Java and OpenSource Engine