2019独角兽企业重金招聘Python工程师标准>>>

/*
 * BDB je操作核心类
 */
package com.ego.data.db.bdb;

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>1、创建BDB数据库对象
 * <p>&nbsp;&nbsp; BDB db=new BDB(new File("D:/gradel"));
 * <br>2、打开数据库
 * <p>&nbsp;&nbsp;db.openDatabase();或db.openDatabase(new File("D:/grade2"))
 * <br>3、打开数据表
 * <p>&nbsp;&nbsp; db.openTable("v");
 * <br>4、添加数据
 * <p>&nbsp;&nbsp; db.addInt("w", 1);或db.add("w",1);db.add("w",1)这种形式最好不要用,因为取值的时候是按照值类型方法取得的。
 * <br>添加值应与取得值一致,否则会出错。
 * <br>5、获取数据
 * <p>&nbsp;&nbsp; db.getInt("w", 1);
 * <br>6、修改数据
 * <p>&nbsp;&nbsp; db.updateInt("w", 5);
 * <p><b>如果要存储序列化对象,还要在存储前调用setStoreSerialObject(String classInfoStoreTableName)指定存储类信息的表名。
 * <br>7、关闭数据库
 * <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());

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) { 
            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);
       }

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());

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);
        }
    
    }
   
}

转载于:https://my.oschina.net/u/436274/blog/89988

BerkeleyDB-JE数据库操作封装相关推荐

  1. 封装php框架视频教程_自编PHP框架一(数据库操作封装)

    自编PHP框架之数据库PDO层封装和模型类部分方法的编写 如果你是喷子,问我造轮子花这么多精力有什么用的话,那就走,看看我的这篇文章 为什么我要写自己的框架?框架所有的代码都在笔者的Github上做展 ...

  2. 数据库封装 sql server mysql_sqlserver数据库操作封装

    1 public classSQLServerDatabase2 {3 private static SqlConnection m_Connection = null;4 5 public SQLS ...

  3. Qt sqlite 数据库操作封装

    封装接口: 1.生成数据库文件 2.打开数据库 3.关闭数据库 4.执行Sql语句 5.增删改查的实现及重载接口 6.事务操作:taransction和commit 直接贴代码 sqliteDb.h ...

  4. PHP mysqli 扩展库(面向对象/数据库操作封装/事务控制/预编译)

    1.和mysql扩展库的区别: (1   安全性.稳定性更高 (2  提供了面向对象和面向过程两种风格 2.php.ini  中的  extension=php_mysqli.dll 解除封印 3.面 ...

  5. php面向对象封装mysql_PHP mysqli 扩展库(面向对象/数据库操作封装/事务控制/预编译)...

    1.和mysql扩展库的区别: (1   安全性.稳定性更高 (2  提供了面向对象和面向过程两种风格 2.php.ini  中的  extension=php_mysqli.dll 解除封印 3.面 ...

  6. python数据库操作封装_Python 封装一个操作mysql的类

    import pymysql class MysqlOperation(): def __init__(self, host, user, pwd, port, db): self.host = ho ...

  7. python - 接口自动化测试 - MysqlUtil - 数据库操作封装

    # -*- coding:utf-8 -*-''' @project: ApiAutoTest @author: Jimmy @file: mysql_util.py @ide: PyCharm Co ...

  8. 小博老师解析Java核心技术 ——JDBC数据库操作类封装

    2019独角兽企业重金招聘Python工程师标准>>> [引言] 我们在学习Java编程时,连接数据库技术(JDBC)是一项必备技能,我们经常需要读取或操作持久性存储的结构化数据.那 ...

  9. 实验六JDBC数据库操作_JAVA

    实验目的: 1.熟悉数据库基本操作 2.掌握利用JDBC进行数据库的连接 3.利用语句对象Statement和PreparedStatement对表.记录.列进行增.删.改.查等操作 4.将数据库操作 ...

最新文章

  1. java上传网络图片_java网络编程之图片上传
  2. Python 微信机器人:调用电脑摄像头时时监控功能实现演示,调用电脑摄像头进行拍照并保存
  3. Anaconda conda常用命令
  4. SQLServe错误整理
  5. webpack 的webpack.config文件配置css-loader,style-loader注意的问题
  6. 简单聊一聊PRINCE2与PMP的区别
  7. Kubernetes 搭建 ES 集群(存储使用 cephfs)
  8. iOS不得姐项目--精华模块上拉下拉的注意事项,日期显示,重构子控制器,计算cell的高度(只计算一次),图片帖子的显示...
  9. 数字电路:常见的锁存器浅析
  10. FreeSSL.cn 创建免费 https 证书
  11. excel图形二(雷达图、瀑布图甘特图、旭日图、树状图、组合图)与动态图
  12. 签offer VS 签三方
  13. 1314520用计算机怎么算,表白公式数学公式抖音 抖音1314520怎么计算,快用计算器表白?...
  14. html首行缩进2字符,可以使用CSS属性中的【text-indent】进行设置。
  15. 批量登录qq空间,点击推广链接,增加点击量
  16. javascript原生初级到非凡-姜威-专题视频课程
  17. 一种修改MCU主频的方法:类观察者模式
  18. html获取请求header,获取HTTP header信息
  19. android dlna uri,DLNA 在自己的APP 中添加投屏功能
  20. from Crypto.Cipher import AES

热门文章

  1. DDD(领域驱动设计)系列之一-DomainPrimitive
  2. mybatis源码学习篇之——执行流程分析
  3. 挂载镜像SD卡的FAT32文件系统分区到Linux中
  4. SpringBoot中Configure注解和Bean注解的使用
  5. Android 沉浸式状态栏
  6. 网关冗余工作原理(总结)
  7. PHP 实现获取服务器端IP地址
  8. DevExpress控件XtraGrid的Master-Detail用法 z
  9. [redis数据结构]之 hash类型
  10. Python 正则模块的应用