BerkeleyDB-JE數據庫操做封裝

/*
 * BDB je操做核心類
 */
package com.ego.data.db.bdb; java

import com.ego.file.Directory;
import com.sleepycat.bind.EntryBinding;
import com.sleepycat.bind.serial.SerialBinding;
import com.sleepycat.bind.serial.StoredClassCatalog;
import com.sleepycat.bind.tuple.TupleBinding;
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.Environment;
import com.sleepycat.je.EnvironmentConfig;
import com.sleepycat.je.LockMode;
import com.sleepycat.je.OperationStatus;
import com.sleepycat.je.Transaction;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.util.logging.Level;
import java.util.logging.Logger; 數據庫

/**
 * BDB je操做核心類。
 * <p>功能:
 * <br>打開(建立數據庫)、打開(建立表)、輸入數據、獲取數據。
 * <br>注意;數據表的默認屬性是表不存在自動建立,表打開方式可讀可寫,不支持多重記錄,不支持事務。默認不支持多重記錄,若是打
 * 開表寫數據時是用多重記錄配置打開,那麼在讀時也應用多重記錄配置打開,不然出錯。默認狀況下,不支持相同記錄(忽略相同記錄添加),
 * 相同記錄即鍵和值都與既存記錄相等。
 * <p>步驟:
 * <br>一、建立BDB數據庫對象
 * <p>&nbsp;&nbsp; BDB db=new BDB(new File("D:/gradel"));
 * <br>二、打開數據庫
 * <p>&nbsp;&nbsp;db.openDatabase();或db.openDatabase(new File("D:/grade2"))
 * <br>三、打開數據表
 * <p>&nbsp;&nbsp; db.openTable("v");
 * <br>四、添加數據
 * <p>&nbsp;&nbsp; db.addInt("w", 1);或db.add("w",1);db.add("w",1)這種形式最好不要用,由於取值的時候是按照值類型方法取得的。
 * <br>添加值應與取得值一致,不然會出錯。
 * <br>五、獲取數據
 * <p>&nbsp;&nbsp; db.getInt("w", 1);
 * <br>六、修改數據
 * <p>&nbsp;&nbsp; db.updateInt("w", 5);
 * <p><b>若是要存儲序列化對象,還要在存儲前調用setStoreSerialObject(String classInfoStoreTableName)指定存儲類信息的表名。
 * <br>七、關閉數據庫
 * <p>&nbsp;&nbsp; db.close();  記得關閉很重要。一是釋放資源;二是在寫入或修改數據庫後必須關閉才能寫入到實際數據庫中。若是
 * 用到resultset還必須關閉resultset.close();不然出錯
 */
public class BDB {
    private File dbPath=null;
    private EnvironmentConfig dbConfig=null;
    private Environment db=null;
    private DatabaseConfig tableConfig=null;
    private Database table=null;
    private boolean dbAutoCreate=true;
    private boolean dbReadOnly=false;
    private boolean dbIsTransactional=true;
    private boolean tableAutoCreate=true;
    private boolean tableReadOnly=false;
    private boolean tableIsTransactional=true;
    private String charsetName="utf-8";
    private String classInfoStoreTableName=null;
    private Database classInfoStoreTable=null;
    private boolean isSortedDuplicate=false;
    private Transaction transaction=null;
   /**
    * 構建bdb數據庫對象實例,但數據庫還沒有初始化,及未創建與數據庫的鏈接
    * @param dbPath數據庫的路徑
    */
    public BDB(File dbPath){
        this.dbPath=dbPath;
        if(!this.dbPath.exists())this.dbPath.mkdirs();
    }
    /**
     * 構建bdb數據庫對象實例,但數據庫還沒有初始化,及未創建與數據庫的鏈接
     * @param dbPath數據庫的路徑
     * @param autoCreate若是數據庫不存在是否建立
     */
   
    public BDB(File dbPath,boolean autoCreate){
        this.dbPath=dbPath;
        if(!this.dbPath.exists())this.dbPath.mkdirs();
    }
    //打開數據庫操做
   /**
    * 數據庫初始化,即建立與指定數據庫的鏈接
    * @return 數據庫對象,即Environment對象
    */
    public Environment openDatabase(){
        this.dbConfig=new EnvironmentConfig().setAllowCreate(dbAutoCreate).setReadOnly(dbReadOnly).setTransactional(dbIsTransactional);
        return this.db=new Environment(dbPath, dbConfig);
    }
    /**
     * 數據庫初始化,即建立與指定數據庫的鏈接
     * @param autoCreate數據庫不存在是否自動建立,true自動建立
     * @param readOnly打開數據庫是否只讀
     * @param isTransactional數據庫是否支持事務處理
     * @return 數據庫對象,即Environment對象
     */
    public Environment openDatabase(boolean autoCreate,boolean readOnly,boolean isTransactional){
        this.dbConfig=new EnvironmentConfig().setAllowCreate(autoCreate).setReadOnly(readOnly).setTransactional(isTransactional);
        return this.db=new Environment(dbPath, dbConfig);
    }
    /**
     * 數據庫初始化,即建立與指定數據庫的鏈接
     * @param dbConfig數據庫配置對象EnvironmentConfig
     * @return  數據庫對象,即Environment對象
     */
    public Environment openDatabase(EnvironmentConfig dbConfig){
        this.dbConfig=dbConfig;
        return this.db=new Environment(dbPath, dbConfig);
    }
    /**
     * 打開數據庫,以給定的參數數據庫地址打開數據庫。之後的操做對象將是此時打開的數據庫
     * @param databasePath數據庫地址
     * @return 數據庫對象,即Environment對象
     */
    public Environment openDatabase(File databasePath){
        this.dbConfig=dbConfig;
        return this.db=new Environment(databasePath, dbConfig);
    }
    /**
     * 打開數據庫,以給定的參數數據庫地址和數據庫屬性配置對象打開數據庫。之後的操做對象將是此時打開的數據庫
     * @param databasePath數據庫地址
     * @param dbCofig
     * @return 數據庫對象,即Environment對象
     */
    public Environment openDatabase(File databasePath,EnvironmentConfig dbCofig){
        this.dbConfig=dbConfig;
        return this.db=new Environment(databasePath,dbCofig);
    }
   
    //打開數據表操做
    /**
     * 打開指定名稱的表,默認屬性爲不存在則建立,不爲只讀,支持事務處理
     * @param tableName代表
     * @return 數據表Database
     * @throws Exception若是還沒有創建數據庫鏈接拋出
     */
    public Database openTable(String tableName) throws Exception{
        return this.opentTable(tableName,true,false, false,null,null);
    }
    /**
     * 打開指定名稱的表,
     * @param tableName表名
     * @param tableAutoCreate不存在是否建立
     * @param tableReadOnly是否以只讀打開
     * @param isSortedDuplicate是否支持多重記錄
     * @return  Database數據表
     * @throws  Exception若是還沒有創建數據庫鏈接拋出
     */
    public Database openTable(String tableName,boolean tableAutoCreate,
            boolean tableReadOnly,boolean isSortedDuplicate) throws Exception{
        return this.opentTable(tableName,tableAutoCreate,tableReadOnly, isSortedDuplicate,null,null);
    }
    /**
     * 打開指定名稱的表,
     * @param tableName表名
     * @param tableConfig表的配置
     * @return Database
     * @throws Exception若是還沒有創建數據庫鏈接拋出
     */
    public Database openTable(String tableName,DatabaseConfig tableConfig) throws Exception{
        return this.opentTable(tableName,true,false, false,tableConfig,null);
    }
    /**
     * 打開指定名稱的表,
     * @param tableName表名
     * @param tableConfig表的配置
     * @param transaction事務處理對象
     * @return Database
     * @throws Exception若是還沒有創建數據庫鏈接拋出
     */
    public Database opentTable(String tableName,DatabaseConfig tableConfig,
            Transaction transaction) throws Exception{
        this.transaction=transaction;
        return this.opentTable(tableName,true,false, false,tableConfig,transaction);
    }
   
    private Database opentTable(String tableName,boolean tableAutoCreate,boolean tableReadOnly,
            boolean isSortedDuplicate,DatabaseConfig tableConfig,Transaction transaction) throws Exception{
       if(this.db==null)throw new Exception("hava not connect the database");
       this.tableConfig=tableConfig!=null?tableConfig:new DatabaseConfig().setAllowCreate(tableAutoCreate)
               .setReadOnly(tableReadOnly).setSortedDuplicates(isSortedDuplicate).setTransactional(dbIsTransactional);
       this.table=db.openDatabase(transaction, tableName, this.tableConfig); 
       this.isSortedDuplicate=this.table.getConfig().getSortedDuplicates();
       return  this.table;
    }
    /**
     * 若是要存儲序列化對象類型數據,還須要指定一個存儲類信息數據表的名字
     * @param classTableName 要保存類信息的表名字
     */
     public void setStoreSerialObject(String classInfoStoreTableName) throws Exception{
        if(this.db==null)throw new Exception("hava not connect the database");
        if(classInfoStoreTableName==null)throw new Exception("classInfoStoreTableNam can't be null");
        this.classInfoStoreTableName=classInfoStoreTableName;
        this.classInfoStoreTable=db.openDatabase(null,classInfoStoreTableName,new DatabaseConfig().setAllowCreate(dbAutoCreate).setSortedDuplicates(false));
    }
     /**
      * 返回。。。。此功能暫不支持
      * @deprecated
      * @return 。。。
      */
     public String getInfoStoreTableName(){
       return this.classInfoStoreTableName;
    }
   
    //數據表操做開始
    /**
     * 獲取指定關鍵詞的字符串形式值,若是表支持多重記錄,則若是鍵對應多個值,則返回第一條記錄
     * @param key要獲取的鍵
     * @return 對應鍵的值,若是對應的沒有值則返回null,若是設置了多重記錄就返回第一條
     * @throws Exception
     */
   
    public String getString(String key) throws Exception { 
       checkDbAndTable();
       byte[] theKey = key.getBytes(this.charsetName); 
       DatabaseEntry queryKey = new DatabaseEntry(theKey); 
       DatabaseEntry storeValue = new DatabaseEntry(); 
       OperationStatus status = table.get(this.transaction, queryKey,storeValue, LockMode.DEFAULT); 
       if (status == OperationStatus.SUCCESS) { 
          return new String(storeValue.getData(), this.charsetName); 
       } 
       return null; 
    }
    /**
     * 獲取指定關鍵詞的證型數值形式值。若是表支持多重記錄,則若是鍵對應多個值,則返回第一條記錄
     * @param key
     * @return int,若是沒有找到對應的值,默認爲0
     * @throws Exception
     */
    public int getInt(String key) throws Exception { 
      
       int ret = 0;
       try {
            ret =getNumeric(key,ret);
        } catch (Exception ex) {
            ret = 0;
        }
       return ret;
    }
   
    /**
     * 獲取指定關鍵詞的證長型數值形式值。若是表支持多重記錄,則若是鍵對應多個值,則返回第一條記錄
     * @param key
     * @return long,若是沒有找到對應的值,默認爲0
     * @throws Exception 若是沒有找到對應鍵的值則拋出錯誤
     */
     public long getLong(String key) throws Exception { 
      
       long ret=0;
       try {
            ret =getNumeric(key,ret);
        } catch (Exception ex) {
            ret = 0;
        }
       return ret;
    }
    /**
     * 獲取指定關鍵詞的雙精度型數值形式值
     * @param key
     * @return double,若是沒有找到對應的值,默認爲0
     * @throws Exception
     */
    public double getDouble(String key) throws Exception { 
      
       double ret = 0;
       try {
            ret =getNumeric(key,ret);
        } catch (Exception ex) {
            ret = 0;
        }
       return ret;
    }
    /**
     * 獲取指定關鍵詞的單精度型數值形式值
     * @param key
     * @return float,若是沒有找到對應的值,默認爲0
     * @throws Exception
     */
    public float getFloat(String key) throws Exception  { 
      
       float ret = 0;
        try {
            ret =getNumeric(key,ret);
        } catch (Exception ex) {
            ret = 0;
        }
       return ret;
    }
    //獲取數值型數據
    private <E > E getNumeric(String key,E type) throws Exception{
       checkDbAndTable();
       byte[] theKey = key.getBytes(this.charsetName); 
       DatabaseEntry queryKey = new DatabaseEntry(theKey); 
       DatabaseEntry storeValue = new DatabaseEntry();
      
       EntryBinding myBinding =TupleBinding.getPrimitiveBinding(type.getClass());
       OperationStatus retVal = table.get(this.transaction, queryKey,storeValue,  LockMode.DEFAULT);
      
       E ret;
       if (retVal == OperationStatus.SUCCESS) { 
           ret = (E) myBinding.entryToObject(storeValue);
       }else{
           throw new Exception("not found");
       }
       return ret;
    }
  
    /**
     * 從BDB數據表中獲取記錄
     * @param <T>泛型參數
     * @param key要得到的鍵
     * @param cl獲取對象的class對象
     * @return若是找到對應值返回值,如沒有返回null
     * @throws Exception 若是數據庫沒有鏈接或存儲數據或存儲類信息的表沒有打開拋出異常
     */
    public <T> T getSerialObject(String key,T serialObject) throws Exception { 
       checkDbAndTable();
       if(this.classInfoStoreTable==null) throw new Exception("the table that store class information dos't exsit");
      
       StoredClassCatalog classCatalog = new StoredClassCatalog(this.classInfoStoreTable);
        // Create the binding建立綁定
       EntryBinding dataBinding = new SerialBinding(classCatalog,serialObject.getClass()); this


       byte[] theKey = key.getBytes(this.charsetName);  .net

       DatabaseEntry queryKey = new DatabaseEntry(theKey);
       // Create the DatabaseEntry for the data. Use the EntryBinding object用入口綁定對象爲數據建立數據庫入口
       // that was just created to populate the DatabaseEntry
       DatabaseEntry value = new DatabaseEntry();
  
       OperationStatus retVal = table.get(this.transaction, queryKey,value,  LockMode.DEFAULT);
       if (retVal == OperationStatus.SUCCESS) { 
            T retrievedData = (T) dataBinding.entryToObject(value);
            return retrievedData; 
       } 
       return null; 
   } 
    /**
     * 獲取自定義記錄綁定對象數據
     * @param <E>返回的類型
     * @param key獲取的鍵
     * @param tupleBinding自定義記錄綁定器
     * @return 存在返回成功,反之false
     * @throws Exception
     */
     public <E> E getTupleObject(String key,TupleBinding tupleBinding) throws Exception { 
       checkDbAndTable();
 
       byte[] theKey = key.getBytes(this.charsetName); 
       DatabaseEntry queryKey = new DatabaseEntry(theKey);
       // Create the DatabaseEntry for the data. Use the EntryBinding object用入口綁定對象爲數據建立數據庫入口
       // that was just created to populate the DatabaseEntry
       DatabaseEntry value = new DatabaseEntry();
  
       OperationStatus retVal = table.get(this.transaction, queryKey,value,  LockMode.DEFAULT);
       if (retVal == OperationStatus.SUCCESS) { 
            E retrievedData = (E) tupleBinding.entryToObject(value);
            return retrievedData; 
       } 
       return null; 
    } 
     /**
      * 獲取表中的全部記錄保存在resultset中
      * @return ResultSet結果記錄集
      * @throws Exception
      */
     public ResultSet  getAll() throws Exception{
        checkDbAndTable();
        Cursor cursor=this.table.openCursor(transaction, CursorConfig.DEFAULT);
        return new ResultSet(cursor, isSortedDuplicate, classInfoStoreTable,this.charsetName) ;  
     }
     /**
      * 獲取表中的指定記錄保存在resultset中
      * @param key
      * @return
      * @throws Exception
      */
     public ResultSet  get(String key) throws Exception{
        checkDbAndTable();
        Cursor cursor=this.table.openCursor(transaction, CursorConfig.DEFAULT);
        ResultSet resultSet=new ResultSet(cursor, isSortedDuplicate, classInfoStoreTable,this.charsetName,key) ;  
        return resultSet;  
     }
    /**
     * 向數據表中插入以字符串形式指定的數據
     * @param key鍵
     * @param 要插入的字符串值
     * @return OperationStatus,若是表支持多重記錄,且鍵已經存在,添加一個新紀錄;若是表不支持多重記錄,且鍵已經存在,會返回已經存在
     * @throws Exception 若是沒有鏈接數據庫或沒有打開表拋出錯誤
     */ 
    public OperationStatus addString(String key, String value) throws Exception { 
       return add(key,value);
   } 
    /**
     * 向數據表中插入以整型形式指定的數據
     * @param key鍵
     * @param 要插入的整型數值
     * @return OperationStatus,若是表支持多重記錄,且鍵已經存在,添加一個新紀錄;若是表不支持多重記錄,且鍵已經存在,會返回已經存在
     * @throws Exception 若是沒有鏈接數據庫或沒有打開表拋出錯誤
     */  
    public OperationStatus addInt(String key, int value) throws Exception { 
       return add(key,value); 
   } 
    /**
     * 向數據表中插入以雙精度形式指定的數據
     * @param key鍵
     * @param 要插入的雙精度型數值
     * @return OperationStatus,若是表支持多重記錄,且鍵已經存在,添加一個新紀錄;若是表不支持多重記錄,且鍵已經存在,會返回已經存在
     * @throws Exception 若是沒有鏈接數據庫或沒有打開表拋出錯誤
     */  
    public OperationStatus addDouble(String key, double value) throws Exception { 
       return add(key,value);
   }
    /**
     * 向數據表中插入以單精度形式指定的數據.
     * @param key鍵
     * @param 要插入的單精度型數值
     * @return OperationStatus,若是表支持多重記錄,且鍵已經存在,添加一個新紀錄;若是表不支持多重記錄,且鍵已經存在,會返回已經存在
     * @throws Exception 若是沒有鏈接數據庫或沒有打開表拋出錯誤
     */  
    public OperationStatus addFloat(String key, float value) throws Exception {   
       return add(key,value); 
   } 
    /**
     * 添加原始類型數據。若是表支持多重記錄,且鍵已經存在,添加一個新紀錄;若是表不支持多重記錄,且鍵已經存在,會返回已經存在
     * @param <E>原始類型
     * @param key
     * @param value
     * @return
     * @throws Exception
     */
    public <E > OperationStatus add(String key,E value) throws Exception{
       checkDbAndTable();
       byte[] theKey = key.getBytes(this.charsetName); 
       DatabaseEntry queryKey = new DatabaseEntry(theKey); 
       DatabaseEntry storeValue = new DatabaseEntry();
      
       EntryBinding myBinding =TupleBinding.getPrimitiveBinding(value.getClass());
       myBinding.objectToEntry(value, storeValue);
       OperationStatus status;
       if(this.isSortedDuplicate){ 
           status = table.put(this.transaction,queryKey, storeValue)  ;
       }else{ 
           status = table.putNoOverwrite(this.transaction, queryKey, storeValue);
       } orm

       return status; 
    }
    /**
     * 將序列化對象存入bdb數據表中
     * @param key鍵
     * @param obj要存儲的序列化對象,這個對象是實現序列化的
     * @return OperationStatus,若是表支持多重記錄,且鍵已經存在,添加一個新紀錄;若是表不支持多重記錄,且鍵已經存在,會返回已經存在
     * @throws Exception 若是數據庫沒有鏈接或存儲數據或存儲類信息的表沒有打開拋出異常
     */
     public OperationStatus addSerialObject(String key, Object  serialValue) throws Exception { 
       checkDbAndTable();
       if(this.classInfoStoreTable==null) throw new Exception("the table that store class information dos't exsit");
      
       StoredClassCatalog classCatalog = new StoredClassCatalog(this.classInfoStoreTable);
        // Create the binding建立綁定
       EntryBinding dataBinding = new SerialBinding(classCatalog, serialValue.getClass());
      
       byte[] theKey = key.getBytes(this.charsetName);  對象

       // Create the DatabaseEntry for the data. Use the EntryBinding object用入口綁定對象爲數據建立數據庫入口
       // that was just created to populate the DatabaseEntry
       DatabaseEntry theData = new DatabaseEntry();
       dataBinding.objectToEntry(serialValue, theData);
      
       OperationStatus status;
       if(this.isSortedDuplicate){ 
           status = table.put(this.transaction,new DatabaseEntry(theKey), theData)  ;
       }else{ 
           status = table.putNoOverwrite(this.transaction, new DatabaseEntry(theKey), theData);
       }
       return status; 
   } 
     /**
      * 將自定義記錄對象數據存儲打開的表中,無重複添加,即鍵不能重複
      * @param <E>泛型
      * @param key存儲在表中的鍵
      * @param obj要存儲的自定義記錄對象
      * @param tupleBinding自定義記錄綁定
      * @return OperationStatus,若是表支持多重記錄,且鍵已經存在,添加一個新紀錄;若是表不支持多重記錄,且鍵已經存在,會返回已經存在
      * @throws Exception
      */
    public <E> OperationStatus addTupleObject(String key,E tupleObj,TupleBinding tupleBinding) throws Exception { 
       checkDbAndTable();
       byte[] theKey = key.getBytes(this.charsetName);  事務

       // Create the DatabaseEntry for the data. Use the EntryBinding object用入口綁定對象爲數據建立數據庫入口
       // that was just created to populate the DatabaseEntry
       DatabaseEntry theData = new DatabaseEntry();
       tupleBinding.objectToEntry(tupleObj, theData);
       //將對象數據存儲在表中
      
       OperationStatus status;
       if(this.isSortedDuplicate){ 
           status = table.put(this.transaction,new DatabaseEntry(theKey), theData)  ;
       }else{ 
           status = table.putNoOverwrite(this.transaction,new DatabaseEntry(theKey), theData);
       }
       return status; 
   } 
  
    /**
     * 刪除指定key的記錄。可使用Database.delete()這個方法來刪除記錄。若是你的database支持多重記錄,
     * 則當前key下的全部記錄都會被刪除,若是隻想刪除多重記錄中的一條則可使用遊標來刪除。
     * 固然你也可使用Environment.truncateDatabase()這個方法來清空database 中的全部記錄
     * @param key要刪除的指定關鍵
     * @return 布爾型,刪除成功返回true
     * @throws Exception
     */
    public boolean delete(String key) throws Exception { 
       checkDbAndTable();
       byte[] theKey = key.getBytes(this.charsetName); 
       OperationStatus status = table.delete(this.transaction, new DatabaseEntry(theKey)); 
       if (status == OperationStatus.SUCCESS) { 
            return true; 
        } 
        return false; 
    }
   
    /**
     * 修改記錄,若是不支持多重記錄則修改指定記錄。若是支持多重記錄,則刪除指定鍵的全部記錄後添加指定修改的鍵/值
     * @param key
     * @param value
     * @return
     * @throws Exception Exception 若是要修改的記鍵不存在拋出錯誤
     */
    public OperationStatus updateString(String key,String value) throws Exception{
       checkDbAndTable();
       return update(key,value); 
    }
    /**
     * 修改記錄,若是不支持多重記錄則修改指定記錄。若是支持多重記錄,則刪除指定鍵的全部記錄後添加指定修改的鍵/值
     * @param key
     * @param value
     * @return
     * @throws Exception Exception 若是要修改的記鍵不存在拋出錯誤
     */
    public OperationStatus updateInt(String key, int value) throws Exception { 
       checkDbAndTable();
       return update(key,value); 
    }
    /**
     * 修改記錄,若是不支持多重記錄則修改指定記錄。若是支持多重記錄,則刪除指定鍵的全部記錄後添加指定修改的鍵/值
     * @param key
     * @param value
     * @return
     * @throws Exception Exception 若是要修改的記鍵不存在拋出錯誤
     */
    public OperationStatus updateDouble(String key, double value) throws Exception { 
       checkDbAndTable();
       return update(key,value);  
   }
    /**
     * 修改記錄,若是不支持多重記錄則修改指定記錄。若是支持多重記錄,則刪除指定鍵的全部記錄後添加指定修改的鍵/值
     * @param key
     * @param value
     * @return
     * @throws Exception Exception 若是要修改的記鍵不存在拋出錯誤
     */ 
    public OperationStatus updateFloat(String key, float value) throws Exception { 
       checkDbAndTable();
       return update(key,value);   
   } 
    /**
     * 修改原始類型數據。若是不支持多重記錄則修改指定記錄。若是支持多重記錄,則刪除指定鍵的全部記錄後添加指定修改的鍵/值
     * @param <E>修改的原型
     * @param key
     * @param value修改的類型
     * @return
     * @throws Exception 若是要修改的記鍵不存在拋出錯誤
     */
    public <E  > OperationStatus update(String key,E value) throws Exception{
       checkDbAndTable();
       Cursor cursor =this.table.openCursor(transaction, CursorConfig.DEFAULT);
      
       DatabaseEntry queryKey = new DatabaseEntry(key.getBytes(this.charsetName));
       DatabaseEntry storeValue = new DatabaseEntry();
      
       OperationStatus retVal = cursor.getSearchKey(queryKey, storeValue,  LockMode.DEFAULT);
       if(retVal!=OperationStatus.SUCCESS){
           cursor.close();
           return OperationStatus.NOTFOUND;
       }
       DatabaseEntry replacementData =  new DatabaseEntry();
       EntryBinding myBinding =TupleBinding.getPrimitiveBinding(value.getClass());
       myBinding.objectToEntry(value, replacementData);
      
       //若是是多重記錄,則刪除記錄再添加
       if(this.isSortedDuplicate){
           delete(key);
           retVal=add(key, value);
       }else{
           retVal=cursor.putCurrent(replacementData);
       }
       cursor.close();
       return retVal; 
    }
    /**
     * 修改記錄,若是不支持多重記錄則修改指定記錄。若是支持多重記錄,則刪除指定鍵的全部記錄後添加指定修改的鍵/值
     * @param key鍵
     * @param serialValue要存儲的序列化對象,這個對象是實現序列化的
     * @return
     * @throws
     */
     public <T> OperationStatus updateSerialObject(String key, Object serialValue,T serialObject) throws Exception { 
       checkDbAndTable();
       if(this.classInfoStoreTable==null) throw new Exception("the table that store class information dos't exsit");
       Cursor cursor =this.table.openCursor(transaction, CursorConfig.DEFAULT);
      
       DatabaseEntry queryKey = new DatabaseEntry(key.getBytes(this.charsetName));
       DatabaseEntry storeValue = new DatabaseEntry();
      
       OperationStatus retVal = cursor.getSearchKey(queryKey, storeValue,  LockMode.DEFAULT);
       if(retVal!=OperationStatus.SUCCESS){
           cursor.close();
           return OperationStatus.NOTFOUND;
       }
       DatabaseEntry replacementData =  new DatabaseEntry();
      
       StoredClassCatalog classCatalog = new StoredClassCatalog(this.classInfoStoreTable);
        // Create the binding建立綁定
       EntryBinding dataBinding = new SerialBinding(classCatalog, serialObject.getClass()); utf-8

       DatabaseEntry replacementDatat = new DatabaseEntry();
       dataBinding.objectToEntry( serialValue, replacementData);
         //若是是多重記錄,則刪除記錄再添加
       if(this.isSortedDuplicate){
           delete(key);
           retVal=addSerialObject(key,  serialValue);
       }else{
           retVal=cursor.putCurrent(replacementData);
       }
       cursor.close();
       return retVal; 
   } 
    
   
    /**
     * 修改自定義記錄。若是不支持多重記錄則修改指定記錄。若是支持多重記錄,則刪除指定鍵的全部記錄後添加指定修改的鍵/值
     * @param <E>自定義對象類型
     * @param key要修改的鍵
     * @param tupleValue新對象值
     * @param tupleBinding指定的記錄綁定對象
     * @return
     * @throws Exception
     */
    public <E> OperationStatus updateTupleObject(String key,E tupleValue,TupleBinding tupleBinding) throws Exception { 
        checkDbAndTable();
        Cursor cursor =this.table.openCursor(transaction, CursorConfig.DEFAULT);
       
        DatabaseEntry queryKey = new DatabaseEntry(key.getBytes(this.charsetName));
        DatabaseEntry storeValue = new DatabaseEntry();
      
        OperationStatus retVal = cursor.getSearchKey(queryKey, storeValue,  LockMode.DEFAULT);
        if(retVal!=OperationStatus.SUCCESS){
           cursor.close();
           return OperationStatus.NOTFOUND;
       }
        DatabaseEntry replacementData = new DatabaseEntry();
        tupleBinding.objectToEntry( tupleValue, replacementData);
         //若是是多重記錄,則刪除記錄再添加
       if(this.isSortedDuplicate){
           delete(key);
           retVal=addTupleObject(key, tupleValue, tupleBinding);
       }else{
           retVal=cursor.putCurrent(replacementData);
       }
       cursor.close();
      
       return retVal; 
   }
   
    //檢查數據庫或數據表是否存在
    private void checkDbAndTable() throws Exception{
        if(this.db==null ||this.table==null)throw new Exception("hava not connect the database or do not open the table");   
    }
    /**
     * 關閉數據庫及表。在修改、寫入數據後必須調用此方法,不然數據不能寫入物理數據庫
     */
    public void close(){
        if(this.table!=null){
            this.tableConfig=null;
            this.table.close();
        }
        if(this.db!=null){
            this.dbConfig=null;
            this.db.close();
        }
    }
    public static void main(String[] args){
        try {
            BDB db=new BDB(new Directory("D:/gradel/f", true));
            Environment e=  db.openDatabase();
            db.openTable("b", true, false, true);
            db.addString("2013-03-04","2012-02-04");
            db.addString("2012-02-12", "hhhhhhhh");
            db.addString("2012-03-04", "5555");
            db.addString("2012-12-04","dddddddddddd");
            db.addString("2013-02-04", "hhhhhhhh");
            db.addString("9013-08-04", "5555");
            db.addString("a","a1");
            db.addString("a", "a2");
            db.addString("a", "a3");
            db.addString("a","a4");
            db.addString("a", "a5");
            db.addString("a", "a6");
            db.addString("a","a1");
            db.addString("a", "a2");
            db.addString("a", "a3");
            db.addString("a","a4");
            db.addString("a", "a5");
            db.addString("a", "a6");
            db.addString("a","a1yyyyyyyyyyyyyyyyyyyyyyyyy7777");
            db.addString("a", "a2");
            db.addString("a", "ayyyyyyyyyyy3");
            db.addString("a","a4");
            db.addString("a", "a577777777777");
            db.addString("a6ttt", "a6");
         // db.updateInt("o",9);
         // db.update("5",4444444);
         // db.add("f",7788);
            db.close();
     
           
             BDB dbb=new BDB(new Directory("D:/gradel/f", true));
             dbb.openDatabase();
             dbb.openTable("b", true, false, true);
    ResultSet rs=dbb.get("a");
     //    ResultSet rs=dbb.getAll();
         //  System.out.print(rs.first());
      while(rs.next()){
           System.out.print(rs.getCurrentPostion());
       System.out.println(rs.getKey()+"____"
        +rs.getString());
         }
             System.out.println(rs.getRecordCount());
        
        // System.out.println(rs.moveTo(1));
           //  rs.next();
      //  rs.moveTo(0); rs.next();
             rs.setPageSize(2);
             rs.setCurrentPage(1);
          //  rs.first();;
               System.out.println(rs.getCurrentPostion());
           System.out.println(rs.getKey()+"____"
                     +rs.getString());
            
            rs.close();
            dbb.close();
 
        } catch (Exception ex) {
            Logger.getLogger(BDB.class.getName()).log(Level.SEVERE, null, ex);
        }
    
    }
   
} 資源

相關文章
相關標籤/搜索