Berkeley DB Java Edition 基本示例

 

package test;

import com.sleepycat.je.*;

import com.sleepycat.bind.EntryBinding;

import com.sleepycat.bind.tuple.TupleBinding;

import com.sleepycat.bind.serial.StoredClassCatalog;

import com.sleepycat.bind.serial.SerialBinding;

import java.io.File;

public class test {

    public static void main(String[] args) {

   

    }

   

    /**

     * 打開和關閉環境,示例一

     *

     */

    public void eg1(){

        //----打開環境,如果不存在,則創建一個------------

        Environment myDbEnvironment=null;

        try {

            EnvironmentConfig envConfig = new EnvironmentConfig();

            envConfig.setAllowCreate(true); //true不存在就創建,false如果不存在則打開環境失敗

            //envConfig.setReadOnly(true); //true 以只讀方式打開,如果是多進程應用,每個進程都要設置爲true

            //envConfig.setTransactional(true);//true支持事務,false不支持,默認false。可以更改配置文件來設置此參數。

            myDbEnvironment = new Environment(new File(".//"), envConfig);//環境所在路徑

            java.util.List myDbNames = myDbEnvironment.getDatabaseNames(); //得到所有的數據庫的名字

            for(int i=0; i < myDbNames.size(); i++) {

                System.out.println("Database Name: " + (String)myDbNames.get(i));

            }

        } catch (DatabaseException dbe) {

            // 錯誤處理

        }

        //----關閉環境----------------

        try {

            if (myDbEnvironment != null) {

            myDbEnvironment.cleanLog(); //在關閉前也最好執行一下cleaner,清理一下日誌文件,因爲delete操作會浪費一些空間

            myDbEnvironment.close();

            }

        } catch (DatabaseException dbe) {

            // 錯誤處理

        }

    }

    /**

     * 打開環境示例二

     *

     */

    public void eg2()

    {

        Environment myEnv = null;

        try{

            myEnv=new Environment(new File("/export/dbEnv"), null);

            EnvironmentMutableConfig envMutableConfig = new EnvironmentMutableConfig();

            envMutableConfig.setCachePercent(50);//設置jecache佔用jvm 內存的百分比。

            //envMutableConfig.setCacheSize(123456);//設定緩存的大小爲123456Bytes

            envMutableConfig.setTxnNoSync(true);//設定事務提交時是否寫更改的數據到磁盤,true不寫磁盤。

            //envMutableConfig.setTxnWriteNoSync(false);//設定事務在提交時,是否寫緩衝的log到磁盤。如果寫磁盤會影響性能,不寫會影響事務的安全。隨機應變。

            myEnv.setMutableConfig(envMutableConfig);

           

           

            EnvironmentStats envStats=myEnv.getStats(null);//調用 Environment.getStats() 返回一個EnvironmentStas對象。調用EnvironmentStats.getNCacheMiss()看命不中數。

            long cacheMisses = envStats.getNCacheMiss(); //這個統計非常重要,尤其針對於長時間運行的應用。 它返回不能夠在內存中命中的請求總數,這可以用來參考指定cache的大小。

           

            //myEnv.getMutableConfig();//得到當前的環境配置信息

        }catch(DatabaseException dbe){}

    }

   

    /**

     * 打開database,以及相關操作

     *

     */

    public void eg3(){

        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); //也可能用DatabaseConfig參數來打開,這樣就可以設置數據庫的屬性,比如是否允許在庫不存在時創建它,是否只讀打開,是否支持事務等。

 

            // Open the database. Create it if it does not already exist.

            DatabaseConfig dbConfig = new DatabaseConfig();

            dbConfig.setAllowCreate(true);

            //transactionnull,不支持事務

            myDatabase = myDbEnvironment.openDatabase(null,"sampleDatabase",dbConfig); //打開庫,要提供一個數據庫名字作爲參數

        } catch (DatabaseException dbe) {

            // Exception handling goes here

        }

       

        //記錄

        String aKey = "key";

        String aData = "data";

 

        try {

            DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));//最好指定編碼方式,因爲不指定編碼會用系統的默認編碼來轉換,因爲系統的默認編碼可能會被人更改。

            DatabaseEntry theData = new DatabaseEntry(aData.getBytes("UTF-8"));

            byte[] myKey = theKey.getData();

            byte[] myData = theData.getData();

           

            //byte數組轉換爲string的方法

            String key = new String(myKey, "UTF-8");

            String data = new String(myData, "UTF-8");

           

            //getput用在非重複的數據存儲,讀寫庫時,注意一個小區別,就是數據庫,是否允許重複的記錄存在,兩個記錄公用一個key,這就是重複的記錄,我們把重複的記錄成爲重複集合。或者叫多重。

            //遊標用於重複數據存儲putget

            //數據記錄在內部是用Btree按照特定排序來存儲的。一般是用key來排序的,key相同的多重數據是按照data來排序。

           

            //記錄Using Database Records

            //記錄是由keydata組成,即所熟悉的key->value,二者都被是有DatabaseEntry封裝的。

            //這個之前也提過很多次了,DatabaseEntry可以封裝原始類型和複雜的對象類型,二者都要被轉換爲byte array存儲,轉換可以使用Bind API來完成

           

            //寫數據

            myDatabase.put(null, theKey, theData);//如果不是可重複數據庫,put將會覆蓋原有的記錄。

            //myDatabase.putNoOverwrite(null, theKey, theData);//不允許覆蓋,不管是否允許數據重複。

           

            //讀數據

            //--myDatabase.getSearchBoth(null, theKey, theData, LockMode.DEFAULT);//查找keydata都匹配的記錄

            //--查詢出來的keydata都是byte數組形式。

            if (myDatabase.get(null, theKey, theData, LockMode.DEFAULT) ==OperationStatus.SUCCESS)

            {

                byte[] retData = theData.getData();

                String foundData = new String(retData, "UTF-8");

                System.out.println("For key: '" + aKey + "' found data: '" +foundData + "'.");

            }

           

            //刪除數據

            myDatabase.delete(null, theKey); //刪除數據

 

          } catch (Exception e) {}

 

        //關閉數據庫

        //如果打開了遊標,關閉時JE會發出警告,讓你關閉他們先。活動狀態的遊標在關閉庫的過程中會產生意想不到的結果,尤其是其他線程在寫庫的過程中。確定所有的訪問都結束後再關閉庫

        try {

            if (myDatabase != null) {

                myDatabase.close();

                myDbEnvironment.renameDatabase(null, "sampleDatabase", "test");//重命名,必須先關閉數據庫

                myDbEnvironment.removeDatabase(null, "sampleDatabase");//刪除數據庫,必須先關閉數據庫

                //myDbEnvironment.truncateDatabase(null, myDatabase.getDatabaseName(),true);//刪除並回收數據庫空間 ,true返回刪除的記錄的數量,false不返回刪除的記錄數量值

            }

 

            if (myDbEnvironment != null) {

                myDbEnvironment.close();

            }

        } catch (DatabaseException dbe) {

            // Exception handling goes here

        }

    }

   

    /**

     * Deferred Write Databases 緩衝寫庫

     *

     * By默認,JE的數據庫是持久化,意思就是說不緩存,寫庫的,這樣多個應用都可以使用,把數據庫設置成非持久化的,就成爲緩衝寫庫。

     * 緩衝寫庫本質上說就是內存級數據庫,這適用於那些臨時的操作。比如把oracle中的數據導入bdb,然後讀bdb cache

     * 緩衝寫庫並不是總是請求磁盤I/O,很重要的一點,緩衝寫庫會在內存不夠用的時候寫磁盤。如果內存夠大,用緩存寫庫那是最好不過了。

     * 調用Database.sync()讓修改過的cache數據寫到磁盤

     * 當重新打開一個緩衝寫庫的環境時,數據庫的狀態是和上一次sync時一致的。如果緩衝寫庫沒有同步,就會當成是空庫。問號,那麼在數據關閉之前一定要syncmaybe yes

     * 程序員很容易就可以把緩衝寫庫的修改存儲到磁盤上,對經常性的修改,增加,及刪除等等的操作的應用也很有用處。通過延遲寫庫,延遲了磁盤IO 這可以提高數據的流量。

     * 注意,當沒有調用sync的庫關閉時而且環境也關閉的時候,cache的修改會丟失。如果沒有關閉環境,所有的cache的修改還是會保留的。

     * 設置庫爲defered or not,然後用DatabaseConfig的選項打開庫。

     */

    public void eg4(){

        Environment myDbEnvironment = null;

        Database myDatabase = null;

        try {

            EnvironmentConfig envConfig = new EnvironmentConfig();

            envConfig.setAllowCreate(true);

            myDbEnvironment = new Environment(new File("/export/dbEnv"), envConfig);

 

            DatabaseConfig dbConfig = new DatabaseConfig();

            dbConfig.setAllowCreate(true); //設置允許創建與否,默認值是false,打開不存在的數據庫會報錯。true的時候,數據庫不存在就創建。

            //dbConfig.setBtreeComparator();//設置B樹比較器,用來比較兩個記錄的key是否相同。

            //dbConfig.setDuplicateComparator();//設置允許key重複的比較器。

            dbConfig.setSortedDuplicates(false);//設置爲true,允許key重複,false的話,put一個存在key的記錄會產生錯誤。如果使用了關聯了多個索引則一定不能支持重複的記錄。

            //dbConfig.setExclusiveCreate(false);//如果true,只能創建,如果存在,則打開失敗If true, the database open fails if the database currently exists. That is, the open must result in the creation of a new database. Default is false.

            //dbConfig.setReadOnly(true);//設置是否只讀

            //dbConfig.setTransactional(true);//設置是否支持事務

            dbConfig.setDeferredWrite(true);  //true爲進行緩衝寫庫,false則不進行緩衝寫庫

            myDatabase = myDbEnvironment.openDatabase(null,"sampleDatabase",dbConfig);

           

           

            String dbName = myDatabase.getDatabaseName();//得到數據庫的名字

            Environment theEnv = myDatabase.getEnvironment();//得到當前數據庫環境

            myDatabase.preload(1024*1024); //預先加載數據到內存,long型參數表示要裝載到內存的數據的最大數

 

            //long類型的數據存儲方法

           

            try {

                String aKey = "myLong";

                DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));

               

               

                Long myLong = new Long(123456789l); 

                DatabaseEntry theData = new DatabaseEntry();

                EntryBinding myBinding = TupleBinding.getPrimitiveBinding(Long.class);

                myBinding.objectToEntry(myLong, theData);

 

                //存儲long類型的數據

                myDatabase.put(null, theKey, theData);

               

                OperationStatus retVal = myDatabase.get(null, theKey, theData,LockMode.DEFAULT);String retKey = null;

                if (retVal == OperationStatus.SUCCESS) {

                   //取得long類型的數據

                    Long theLong = (Long) myBinding.entryToObject(theData);

                    retKey = new String(theKey.getData(), "UTF-8");

                    System.out.println("For key: '" + retKey + "' found Long: '" +

                                        theLong + "'.");

                } else {

                    System.out.println("No record found for key '" + retKey + "'.");

                }

   

            } catch (Exception e) {

                // Exception handling goes here

            }

           

            //implements Serializable 的對象的存儲

           

            try {

                String aKey = "myLong";

                DatabaseEntry theKey = new DatabaseEntry(aKey.getBytes("UTF-8"));

               

                //寫對象

                java.util.Vector data2Store = new java.util.Vector(); //假設他是implements Serializable

                StoredClassCatalog classCatalog = new StoredClassCatalog(myDatabase);

                EntryBinding dataBinding = new SerialBinding(classCatalog, java.util.Vector.class);//指定類型

                DatabaseEntry theData = new DatabaseEntry();

                dataBinding.objectToEntry(data2Store, theData);//綁定數據

                myDatabase.put(null, theKey, theData);

               

                //讀對象

                myDatabase.get(null, theKey, theData, LockMode.DEFAULT);

                java.util.Vector retrievedData = (java.util.Vector) dataBinding.entryToObject(theData);

               

            } catch (Exception e) {

                // Exception handling goes here

            }

           

           

            //做一些處理

            myDatabase.sync(); //當寫完一定量的數據以後,同步要硬盤中

        } catch (DatabaseException dbe) {

            // Exception handling goes here

        }

       

        //關閉數據庫

        try {

            if (myDatabase != null) {

                myDatabase.close();

            }

 

            if (myDbEnvironment != null) {

                myDbEnvironment.close();

            }

        } catch (DatabaseException dbe) {

            // Exception handling goes here

        }

    }

   

    /**

     * Data Persistence 持久化

     * 如果是在內存中修了數據,需要寫到磁盤。

     * 怕因爲系統錯誤引發數據丟失,可以使用transaction,每commit一次,修改都會被保存。

     * 只是用來存放應用臨時數據的話,就不需要用transaction了。

     * 在每次關閉env的時候會執行,也可以在程序中調用執行。

     */

}

/**

 * 特殊對象間的自定義轉換

 *

 */

 

/*

 

package je.gettingStarted;

 

import com.sleepycat.bind.tuple.TupleBinding;

import com.sleepycat.bind.tuple.TupleInput;

import com.sleepycat.bind.tuple.TupleOutput;

 

public class MyTupleBinding extends TupleBinding {

 

    // Write a MyData2 object to a TupleOutput

    public void objectToEntry(Object object, TupleOutput to) {

 

        MyData2 myData = (MyData2)object;

 

        // Write the data to the TupleOutput (a DatabaseEntry).

        // Order is important. The first data written will be

        // the first bytes used by the default comparison routines.

        to.writeDouble(myData.getDouble().doubleValue());

        to.writeLong(myData.getLong());

        to.writeString(myData.getString());

    }

 

    // Convert a TupleInput to a MyData2 object

    public Object entryToObject(TupleInput ti) {

 

        // Data must be read in the same order that it was

        // originally written.

        Double theDouble = new Double(ti.readDouble());

        long theLong = ti.readLong();

        String theString = ti.readString();

 

        MyData2 myData = new MyData2();

        myData.setDouble(theDouble);

        myData.setLong(theLong);

        myData.setString(theString);

 

        return myData;

    }

}

 

 

//==================================

 package je.gettingStarted;

 

import com.sleepycat.bind.tuple.TupleBinding;

import com.sleepycat.je.DatabaseEntry;

 

...

 

TupleBinding keyBinding = new MyTupleBinding();

 

MyData2 theKeyData = new MyData2();

theKeyData.setLong(123456789l);

theKeyData.setDouble(new Double(12345.6789));

theKeyData.setString("My key data");

 

DatabaseEntry myKey = new DatabaseEntry();

 

try {

    // Store theKeyData in the DatabaseEntry

    keyBinding.objectToEntry(theKeyData, myKey);

 

    ...

    // Database put and get activity omitted for clarity

    ...

 

    // Retrieve the key data

    theKeyData = (MyData2) keyBinding.entryToObject(myKey);

} catch (Exception e) {

    // Exception handling goes here

}

*/

 

 

//比較器

 

/*

 

package je.gettingStarted;

 

import java.util.Comparator;

 

public class MyDataComparator implements Comparator {

 

    public MyDataComparator() {}

 

    public int compare(Object d1, Object d2) {

 

        byte[] b1 = (byte[])d1;

        byte[] b2 = (byte[])d2;

 

        String s1 = new String(b1, "UTF-8");

        String s2 = new String(b2, "UTF-8");

        return s1.compareTo(s2);

    }

}

 

使用示例

 

package je.gettingStarted;

 

import com.sleepycat.je.Database;

import com.sleepycat.je.DatabaseConfig;

import com.sleepycat.je.DatabaseException;

 

import java.util.Comparator;   

 

...

 

 

// Environment open omitted for brevity

 

try {

    // Get the database configuration object

    DatabaseConfig myDbConfig = new DatabaseConfig();

    myDbConfig.setAllowCreate(true);

 

    // Set the duplicate comparator class

    myDbConfig.setDuplicateComparator(MyDataComparator.class);

 

    // Open the database that you will use to store your data

    myDbConfig.setSortedDuplicates(true);

    Database myDatabase = myDbEnv.openDatabase(null, "myDb", myDbConfig);

} catch (DatabaseException dbe) {

    // Exception handling goes here

}

 

 */

 

 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章