Java那些事之Berkeley DB

最近一直在使用java,随着使用时间的加长,对java也有了更深入的了解。从今天开始,我会写一些关于java的专题内容,希望大家喜欢,也希望各位多多讨论指正。

 

这一次先介绍一下Berkeley DB的java版本,Berkeley DB Java Edition (JE)。

JE 适合于管理海量的,简单的数据。其中的记录都以简单的键值对保存,即key/value对。由于它操作简单,效率较高,因此受到了广泛的好评。下面我就带领大家看看JE 是如果使用的吧~

JE 下载地址:http://www.oracle.com/technology/software/products/berkeley-db/je/index.html

下载完成解亚后,把JE_HOME/lib/je-.jar 中的jar文件添加到你的环境变量中就可以使用je了。

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

源代码见JE_HOME/src/*.*

 

 

下面是具体的使用代码,大家可以参考一下,注释还是比较详细的,有什么不懂的可以给我留言~

 

View Code
 1 //数据库环境
 2     private  Environment myDbEnvironment = null;
 3     //数据库配置
 4     private  DatabaseConfig dbConfig=null;
 5 //    //数据库游标
 6 //    private  Cursor myCursor = null;
 7     //数据库对象
 8     private  Database myDatabase = null;
 9     //数据库文件名
10     private  String fileName = "";
11     //数据库名称
12     private  String dbName = "";
 1     /*
 2      * 打开当前数据库
 3      */
 4     public  void openDatabase() {
 5         // TODO Auto-generated method stub
 6         try{
 7             CheckMethods.PrintDebugMessage("打开数据库: "+dbName);
 8             EnvironmentConfig envConfig = new EnvironmentConfig();
 9             envConfig.setAllowCreate(true);
10             envConfig.setTransactional(true);
11             envConfig.setReadOnly(false);
12             envConfig.setTxnTimeout(10000, TimeUnit.MILLISECONDS);
13             envConfig.setLockTimeout(10000, TimeUnit.MILLISECONDS);
14             /*
15              *   其他配置 可以进行更改
16                 EnvironmentMutableConfig envMutableConfig = new EnvironmentMutableConfig();
17                 envMutableConfig.setCachePercent(50);//设置je的cache占用jvm 内存的百分比。
18                 envMutableConfig.setCacheSize(123456);//设定缓存的大小为123456Bytes
19                 envMutableConfig.setTxnNoSync(true);//设定事务提交时是否写更改的数据到磁盘,true不写磁盘。
20                 //envMutableConfig.setTxnWriteNoSync(false);//设定事务在提交时,是否写缓冲的log到磁盘。如果写磁盘会影响性能,不写会影响事务的安全。随机应变。
21              *
22              */
23             File file = new File(fileName);
24             if(!file.exists())
25                 file.mkdirs();
26             myDbEnvironment = new Environment(file,envConfig);
27             
28             dbConfig = new DatabaseConfig();
29             dbConfig.setAllowCreate(true);
30             dbConfig.setTransactional(true);
31             dbConfig.setReadOnly(false);
32             //dbConfig.setSortedDuplicates(false);
33             /*
34                 setBtreeComparator 设置用于B tree比较的比较器,通常是用来排序
35                 setDuplicateComparator 设置用来比较一个key有两个不同值的时候的大小比较器。
36                 setSortedDuplicates 设置一个key是否允许存储多个值,true代表允许,默认false.
37                 setExclusiveCreate 以独占的方式打开,也就是说同一个时间只能有一实例打开这个database。
38                 setReadOnly 以只读方式打开database,默认是false.
39                 setTransactional 如果设置为true,则支持事务处理,默认是false,不支持事务。
40             */
41             if(myDatabase == null)
42                 myDatabase = myDbEnvironment.openDatabase(null, dbName, dbConfig);
43             
44             CheckMethods.PrintDebugMessage(dbName+"数据库中的数据个数: "+myDatabase.count());
45             /*
46              *  Database.getDatabaseName()
47                 取得数据库的名称
48                 如:String dbName = myDatabase.getDatabaseName();
49                 
50                 Database.getEnvironment()
51                 取得包含这个database的环境信息
52                 如:Environment theEnv = myDatabase.getEnvironment();
53                 
54                 Database.preload()
55                 预先加载指定bytes的数据到RAM中。
56                 如:myDatabase.preload(1048576l); // 1024*1024
57                 
58                 Environment.getDatabaseNames()
59                 返回当前环境下的数据库列表
60                 Environment.removeDatabase()
61                 删除当前环境中指定的数据库。
62                 如:
63                 String dbName = myDatabase.getDatabaseName();
64                 myDatabase.close();
65                 myDbEnv.removeDatabase(null, dbName);
66                 
67                 Environment.renameDatabase()
68                 给当前环境下的数据库改名
69                 如:
70                 String oldName = myDatabase.getDatabaseName();  
71                 String newName = new String(oldName + ".new", "UTF-8");
72                 myDatabase.close();
73                 myDbEnv.renameDatabase(null, oldName, newName);
74                 
75                 Environment.truncateDatabase()
76                 清空database内的所有数据,返回清空了多少条记录。
77                 如:
78                 Int numDiscarded= myEnv.truncate(null,
79                 myDatabase.getDatabaseName(),true);
80                 CheckMethods.PrintDebugMessage("一共删除了 " + numDiscarded +" 条记录 从数据库 " + myDatabase.getDatabaseName());
81              */
82         }
83         catch(DatabaseException e){
84             CheckMethods.PrintInfoMessage(e.getMessage());
85 
86         }
87     }

 

View Code
 1 /*
 2      * 向数据库中写入记录
 3      * 传入key和value
 4      */
 5     public  boolean writeToDatabase(String key,String value,boolean isOverwrite) {
 6         // TODO Auto-generated method stub
 7         try {
 8               //设置key/value,注意DatabaseEntry内使用的是bytes数组
 9               DatabaseEntry theKey=new DatabaseEntry(StringHelper.TrimString(key).getBytes("UTF-8"));
10               DatabaseEntry theData=new DatabaseEntry(value.getBytes("UTF-8"));
11               OperationStatus res = null;
12               Transaction txn = null;
13               try
14               {
15                   TransactionConfig txConfig = new TransactionConfig();
16                   txConfig.setSerializableIsolation(true);
17                   txn = myDbEnvironment.beginTransaction(null, txConfig);
18                   if(isOverwrite)
19                   {
20                       res = myDatabase.put(txn, theKey, theData);
21                   }
22                   else
23                   {
24                       res = myDatabase.putNoOverwrite(txn, theKey, theData);
25                   }
26                   txn.commit();
27                   if(res == OperationStatus.SUCCESS)
28                   {
29                       CheckMethods.PrintDebugMessage("向数据库" + dbName +"中写入:"+key+","+value);
30                       return true;
31                   } 
32                   else if(res == OperationStatus.KEYEXIST)
33                   {
34                       CheckMethods.PrintDebugMessage("向数据库" + dbName +"中写入:"+key+","+value+"失败,该值已经存在");
35                       return false;
36                   }
37                   else 
38                   {
39                       CheckMethods.PrintDebugMessage("向数据库" + dbName +"中写入:"+key+","+value+"失败");
40                       return false;
41                   }
42               }
43               catch(LockConflictException lockConflict)
44               {
45                   txn.abort();
46                   CheckMethods.PrintInfoMessage("向数据库" + dbName +"中写入:"+key+","+value+"出现lock异常");
47                   CheckMethods.PrintInfoMessage(lockConflict.getMessage());
48                   CheckMethods.PrintInfoMessage(lockConflict.getCause().toString());
49                   CheckMethods.PrintInfoMessage(lockConflict.getStackTrace().toString());
50                                 return false;
51               }
52         }
53         catch (Exception e) 
54         {
55             // 错误处理
56             CheckMethods.PrintInfoMessage("向数据库" + dbName +"中写入:"+key+","+value+"出现错误");
57             
58             return false;
59         }
60     }
View Code
 1 /*
 2      * 关闭当前数据库
 3      */
 4     public  void closeDatabase() {
 5         // TODO Auto-generated method stub    
 6         if(myDatabase != null)
 7         {
 8             myDatabase.close();
 9         }
10         if(myDbEnvironment != null)
11         {
12             CheckMethods.PrintDebugMessage("关闭数据库: " + dbName);
13             myDbEnvironment.cleanLog(); 
14             myDbEnvironment.close();
15         }
16     }
View Code
 1 /*
 2      * 删除数据库中的一条记录
 3      */
 4     public  boolean deleteFromDatabase(String key) {
 5         boolean success = false;
 6            long sleepMillis = 0;
 7         for(int i=0;i<3;i++)
 8         {
 9             if (sleepMillis != 0
10             {
11                 try 
12                 {
13                     Thread.sleep(sleepMillis);
14                 } 
15                 catch (InterruptedException e) 
16                 {
17                     e.printStackTrace();
18                 }
19                 sleepMillis = 0;
20             }
21             Transaction txn = null;
22             try
23             {
24                 TransactionConfig txConfig = new TransactionConfig();
25                 txConfig.setSerializableIsolation(true);
26                 txn = myDbEnvironment.beginTransaction(null, txConfig);
27                 DatabaseEntry theKey;
28                 theKey = new DatabaseEntry(StringHelper.TrimString(key).getBytes("UTF-8"));
29                 OperationStatus res = myDatabase.delete(txn, theKey);
30                 txn.commit();
31                 if(res == OperationStatus.SUCCESS)
32                 {
33                      CheckMethods.PrintDebugMessage("从数据库" + dbName +"中删除:"+key);
34                        success = true
35                        return success;
36                 }
37                 else if(res == OperationStatus.KEYEMPTY)
38                 {
39                      CheckMethods.PrintDebugMessage("没有从数据库" + dbName +"中找到:"+key+"。无法删除");
40                 }
41                 else
42                 {
43                      CheckMethods.PrintDebugMessage("删除操作失败,由于"+res.toString());
44                 }
45                 return false;
46             }
47             catch (UnsupportedEncodingException e) 
48             {
49                 // TODO Auto-generated catch block
50                 
51                 e.printStackTrace();
52                 return false;
53             }
54             catch(LockConflictException lockConflict)
55             {
56                 CheckMethods.PrintInfoMessage("删除操作失败,出现lockConflict异常");
57                 CheckMethods.PrintInfoMessage(lockConflict.getMessage());
58                 CheckMethods.PrintInfoMessage(lockConflict.getCause().toString());
59                 CheckMethods.PrintInfoMessage(lockConflict.getStackTrace().toString());
60                 sleepMillis = 1000;
61                 
62                 continue;
63             }
64             finally 
65             {
66                  if (!success)
67                  {
68                       if (txn != null
69                       {
70                           txn.abort();
71                       }
72                  }
73             }
74         }
75         return false;
76     }
View Code
 1     /*
 2      * 从数据库中读出数据
 3      * 传入key 返回value
 4      */
 5     public String readFromDatabase(String key) {
 6         // TODO Auto-generated method stub
 7         //Database.getSearchBoth()
 8         try {
 9              DatabaseEntry theKey = new DatabaseEntry(StringHelper.TrimString(key).getBytes("UTF-8"));
10              DatabaseEntry theData = new DatabaseEntry();
11              Transaction txn = null;
12              try
13              {
14                  TransactionConfig txConfig = new TransactionConfig();
15                  txConfig.setSerializableIsolation(true);
16                  txn = myDbEnvironment.beginTransaction(null, txConfig);
17                  OperationStatus res = myDatabase.get(txn, theKey, theData, LockMode.DEFAULT);
18                  txn.commit();
19                  if(res == OperationStatus.SUCCESS)
20                  {
21                      byte[] retData = theData.getData();
22                      String foundData = new String(retData, "UTF-8");
23                      CheckMethods.PrintDebugMessage("从数据库" + dbName +"中读取:"+key+","+foundData);
24                      return foundData;
25                  }
26                  else
27                  {
28                      CheckMethods.PrintDebugMessage("No record found for key '" + key + "'.");
29                      return "";
30                  }
31              }
32              catch(LockConflictException lockConflict)
33              {
34                  txn.abort();
35                  CheckMethods.PrintInfoMessage("从数据库" + dbName +"中读取:"+key+"出现lock异常");
36                  CheckMethods.PrintInfoMessage(lockConflict.getMessage());
37                  CheckMethods.PrintInfoMessage(lockConflict.getCause().toString());
38                  CheckMethods.PrintInfoMessage(lockConflict.getStackTrace().toString());
39                  
40                  return "";
41              }
42             
43         } catch (UnsupportedEncodingException e) {
44             // TODO Auto-generated catch block
45             e.printStackTrace();
46             
47             return "";
48         }
49     }
View Code
 1 /*
 2      * 遍历数据库中的所有记录,返回list
 3      */
 4     public  ArrayList<String> getEveryItem() {
 5         // TODO Auto-generated method stub
 6         CheckMethods.PrintDebugMessage("===========遍历数据库"+dbName+"中的所有数据==========");
 7          Cursor myCursor = null;
 8          ArrayList<String> resultList = new ArrayList<String>();
 9          Transaction txn = null;
10          try{
11              txn = this.myDbEnvironment.beginTransaction(nullnull);
12              CursorConfig cc = new CursorConfig();
13              cc.setReadCommitted(true);
14              if(myCursor==null)
15                  myCursor = myDatabase.openCursor(txn, cc);
16              DatabaseEntry foundKey = new DatabaseEntry();
17              DatabaseEntry foundData = new DatabaseEntry();         
18              // 使用cursor.getPrev方法来遍历游标获取数据
19              if(myCursor.getFirst(foundKey, foundData, LockMode.DEFAULT)
20                      == OperationStatus.SUCCESS)
21              {
22                  String theKey = new String(foundKey.getData(), "UTF-8");
23                  String theData = new String(foundData.getData(), "UTF-8");
24                  resultList.add(theKey);
25                  CheckMethods.PrintDebugMessage("Key | Data : " + theKey + " | " + theData + "");
26                  while (myCursor.getNext(foundKey, foundData, LockMode.DEFAULT) 
27                            == OperationStatus.SUCCESS) 
28                  {
29                         theKey = new String(foundKey.getData(), "UTF-8");
30                         theData = new String(foundData.getData(), "UTF-8");
31                         resultList.add(theKey);
32                         CheckMethods.PrintDebugMessage("Key | Data : " + theKey + " | " + theData + "");
33                  }
34              }
35              myCursor.close();
36              txn.commit();
37              return resultList;
38          } 
39          catch (UnsupportedEncodingException e) {
40             // TODO Auto-generated catch block
41             e.printStackTrace();    
42             return null;
43          }
44          catch (Exception e) 
45          {
46              CheckMethods.PrintInfoMessage("getEveryItem处理出现异常");
47              CheckMethods.PrintInfoMessage(e.getMessage().toString());
48              CheckMethods.PrintInfoMessage(e.getCause().toString());
49              
50              txn.abort();
51              if (myCursor != null
52              {
53                  myCursor.close();
54              }
55              return null;
56          }
57     }

 

 由于考虑到多线程,因此上面的方法都采用了事务,这样可以很好的保证数据的正确性。

 

 

 

 

posted @ 2011-06-25 21:22  ~大器晚成~  阅读(12743)  评论(6编辑  收藏  举报