天天看點

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);//設定je的cache占用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){}

    }

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

            //transaction為null,不支援事務

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

            //get和put用在非重複的資料存儲,讀寫庫時,注意一個小差別,就是資料庫,是否允許重複的記錄存在,兩個記錄公用一個key,這就是重複的記錄,我們把重複的記錄成為重複集合。或者叫多重。

            //遊标用于重複資料存儲put和get。

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

            //記錄Using Database Records

            //記錄是由key和data組成,即所熟悉的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);//查找key和data都比對的記錄

            //--查詢出來的key和data都是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

        }

    }

    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

        }

    }

}

//比較器