• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • YouClaw
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

zhuyonghui

zhuyonghui
  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

Berkele DB 4.8 简单实用

 Berkeley DB BteeDatabase简单实用

 

使用BDB C# API进行基于数据库应用程序的开发,需要libdb48.dll,libdb_csharp48.dll和libdb_dotnet48.dll三个动态链接库。首先,在开发的工程中添加libdb_dotnet48.dll的引用,由于libdb_dotnet48.dll需要调用本地代码得到的libdb48d.dll和libdb_csharp48.dll。因此,libdb48d.dll,libdb_csharp48d.dll应放在本工程路径或者环境变量中,以便运行时加载。开发过程中,在代码中添加BDB C# API的命名空间,即“using BerkeleyDB”,便可使用BDB C# API。

 

BerkeleyDB的数据库操作需要借助BteeDatabase类。因此需要先得到BteeDatabase的实例,但是BteeDatabase类会对其它几个类有依赖,必须依赖其它几个类才能创建。

 

 

首先 配置 Berkeley DB 用到得环境变量 libdb48d.dll   libdb_csharp48d.dll 代码如下

 

private void PathEnv()

        {

            try

            {

                String pwd = Environment.CurrentDirectory;

                pwd = Path.Combine(pwd, "..");

                pwd = Path.Combine(pwd, "..");

                if (IntPtr.Size == 4)

                    pwd = Path.Combine(pwd, "Win32");

                else

                    pwd = Path.Combine(pwd, "x64");

#if DEBUG

                pwd = Path.Combine(pwd, "Debug");

#else

                pwd = Path.Combine(pwd, "Release");

#endif

                pwd += ";" + Environment.GetEnvironmentVariable("PATH");

                Environment.SetEnvironmentVariable("PATH", pwd);

            }

            catch (Exception e)

            {

                throw new Exception("Unable to set the PATH environment variable." + "-------" + e.Message);

            }

        }

 

 

 

然后 设置 数据存储位置 以及用到的环境 初始化

 

public void SetUpEnv()

        {

            BerkeleyDB.DatabaseEnvironmentConfig envCfg = new BerkeleyDB.DatabaseEnvironmentConfig();

            envCfg.Create = true;

            envCfg.UseMPool = true;

            envCfg.UseLocking = true;

            envCfg.UseLogging = true;

            envCfg.UseTxns = true;

           

            // Allow multiple threads visit to the environment handle.

            envCfg.FreeThreaded = true;

 

            if (inMem)

                envCfg.Private = true;

            else

                envCfg.RunRecovery = true;

 

            /*

             * Indicate that we want db to internally perform

             * deadlock detection, aborting the transaction that

             * has performed the least amount of WriteData activity

             * in the event of a deadlock.

             */

            envCfg.LockSystemCfg = new BerkeleyDB.LockingConfig();

            envCfg.LockSystemCfg.DeadlockResolution =

                BerkeleyDB.DeadlockPolicy.MIN_WRITE;

 

            if (inMem)

            {

                // Specify in-memory logging.

                envCfg.LogSystemCfg = new BerkeleyDB.LogConfig();

                envCfg.LogSystemCfg.InMemory = true;

 

                /*

                 * Specify the size of the in-memory log buffer

                 * Must be large enough to handle the log data

                 * created by the largest transaction.

                 */

                envCfg.LogSystemCfg.BufferSize = 10 * 1024 * 1024;

 

                /*

                 * Specify the size of the in-memory cache,

                 * large enough to avoid paging to disk.

                 */

                envCfg.MPoolSystemCfg = new BerkeleyDB.MPoolConfig();

                envCfg.MPoolSystemCfg.CacheSize =

                    new BerkeleyDB.CacheInfo(0, 10 * 1024 * 1024, 1);

            }

 

            // Set up the database.

            BerkeleyDB.BTreeDatabaseConfig dbCfg = new BerkeleyDB.BTreeDatabaseConfig();

            dbCfg.AutoCommit = true;

            dbCfg.Creation = BerkeleyDB.CreatePolicy.IF_NEEDED;

            dbCfg.Duplicates = BerkeleyDB.DuplicatesPolicy.NONE;

            dbCfg.FreeThreaded = true;

            dbCfg.ReadUncommitted = true;

           

            /*

                         * Open the environment. Any errors will be caught

                         * by the caller.

                         */

            env = BerkeleyDB.DatabaseEnvironment.Open(directory, envCfg);

 

            /*

             * Open the database. Do not provide a txn handle. This

             * Open is autocommitted because BTreeDatabaseConfig.AutoCommit

             * is true.

             */

            dbCfg.Env = env;

            db = BerkeleyDB.BTreeDatabase.Open(dbName, dbCfg);

            txn = env.BeginTransaction();

        }

 

Berkeley DB是键值数据库,因此定义一个获取键接口,如果你存储的非实体类对象 也可以不继承这个 在存入输入时传入key

 

public interface IPut   

    {       

        string Key { get; }   

}

 

 

 

 

 

数据库的保存与更新

 

public void Set(IPut put)

        {

            Set<IPut>(put.Key, put);

        }

        public void Set<T>(string aKey, T aData)

        {

            Reset();

              //另外Berkeley DB数据库的操作需要借助于序列化

            BinaryFormatter formatter = new BinaryFormatter();

            MemoryStream ms = new MemoryStream();

 

            BerkeleyDB.DatabaseEntry key = new BerkeleyDB.DatabaseEntry();

            dbtFromString(key, aKey);

 

            formatter.Serialize(ms, aData);

 

            Byte[] bytes = ms.GetBuffer();

            BerkeleyDB.DatabaseEntry data = new BerkeleyDB.DatabaseEntry(bytes);

 

            // Put key/data pair within the transaction.

            db.Put(key, data, txn);

        }

 

数据库的删除

 

public void Remove(IPut put)

        {

            Remove(put.Key);

        }

        public void Remove(string aKey)

        {

            BerkeleyDB.DatabaseEntry key = new BerkeleyDB.DatabaseEntry();

            dbtFromString(key, aKey);

            db.Delete(key, txn);

        }

 

 

 

关于添加和删除

 

txn.Commit();

 

寻找键

用键查询值,和hash表一样使用

 

public void Get<T>(ref T put) where T : IPut

        {

            put = Get<T>(put.Key);

        }

 

        public T Get<T>(string aKey)

        {

            Reset();

            BerkeleyDB.DatabaseEntry key = new BerkeleyDB.DatabaseEntry();

            dbtFromString(key, aKey);

            KeyValuePair<BerkeleyDB.DatabaseEntry, BerkeleyDB.DatabaseEntry> pair = db.Get(key, txn);

 

            BinaryFormatter formatter = new BinaryFormatter();

            MemoryStream ms = new MemoryStream(pair.Value.Data);

 

            return (T)formatter.Deserialize(ms);

        }

 

 

 

完整操作封装

 

public class BDB4_8Manager : IDisposable

    {

        /// <summary>       

        /// 数据库目录       

        /// </summary>       

        private string directory;

        /// <summary>       

        /// 数据库文件名       

        /// </summary>       

        private string dbName;

 

        private BerkeleyDB.DatabaseEnvironment env;

 

        private BerkeleyDB.Database db;

 

        private bool inMem;

 

        private BerkeleyDB.Transaction txn;

 

        public BDB4_8Manager()

        {

            directory = @"d:\\db";

            dbName = "testdb.dat";

            inMem = false;

            Init();

        }

        public void Init()

        {

            //检查保存数据路径 没有就创建下

            DirExists();

            //配置 Berkeley DB 用到得环境变量 libdb48d.dll   libdb_csharp48d.dll

            PathEnv();

            //设置环境

            SetUpEnv();

 

        }

 

        private void DirExists()

        {

            if (!Directory.Exists(directory))

            {

                try

                {

                   Directory.CreateDirectory(directory);

                }

                catch

                {

                    throw new Exception("Unable to create " + directory);

                }

            }

        }

        private void PathEnv()

        {

            try

            {

                String pwd = Environment.CurrentDirectory;

                pwd = Path.Combine(pwd, "..");

                pwd = Path.Combine(pwd, "..");

                if (IntPtr.Size == 4)

                    pwd = Path.Combine(pwd, "Win32");

                else

                    pwd = Path.Combine(pwd, "x64");

#if DEBUG

                pwd = Path.Combine(pwd, "Debug");

#else

                pwd = Path.Combine(pwd, "Release");

#endif

                pwd += ";" + Environment.GetEnvironmentVariable("PATH");

                Environment.SetEnvironmentVariable("PATH", pwd);

            }

            catch (Exception e)

            {

                throw new Exception("Unable to set the PATH environment variable." + "-------" + e.Message);

            }

        }

 

        public void SetUpEnv()

        {

            BerkeleyDB.DatabaseEnvironmentConfig envCfg = new BerkeleyDB.DatabaseEnvironmentConfig();

            envCfg.Create = true;

            envCfg.UseMPool = true;

            envCfg.UseLocking = true;

            envCfg.UseLogging = true;

            envCfg.UseTxns = true;

           

            // Allow multiple threads visit to the environment handle.

            envCfg.FreeThreaded = true;

 

            if (inMem)

                envCfg.Private = true;

            else

                envCfg.RunRecovery = true;

 

            /*

             * Indicate that we want db to internally perform

             * deadlock detection, aborting the transaction that

             * has performed the least amount of WriteData activity

             * in the event of a deadlock.

             */

            envCfg.LockSystemCfg = new BerkeleyDB.LockingConfig();

            envCfg.LockSystemCfg.DeadlockResolution =

                BerkeleyDB.DeadlockPolicy.MIN_WRITE;

 

            if (inMem)

            {

                // Specify in-memory logging.

                envCfg.LogSystemCfg = new BerkeleyDB.LogConfig();

                envCfg.LogSystemCfg.InMemory = true;

 

                /*

                 * Specify the size of the in-memory log buffer

                 * Must be large enough to handle the log data

                 * created by the largest transaction.

                 */

                envCfg.LogSystemCfg.BufferSize = 10 * 1024 * 1024;

 

                /*

                 * Specify the size of the in-memory cache,

                 * large enough to avoid paging to disk.

                 */

                envCfg.MPoolSystemCfg = new BerkeleyDB.MPoolConfig();

                envCfg.MPoolSystemCfg.CacheSize =

                    new BerkeleyDB.CacheInfo(0, 10 * 1024 * 1024, 1);

            }

 

            // Set up the database.

            BerkeleyDB.BTreeDatabaseConfig dbCfg = new BerkeleyDB.BTreeDatabaseConfig();

            dbCfg.AutoCommit = true;

            dbCfg.Creation = BerkeleyDB.CreatePolicy.IF_NEEDED;

            dbCfg.Duplicates = BerkeleyDB.DuplicatesPolicy.NONE;

            dbCfg.FreeThreaded = true;

            dbCfg.ReadUncommitted = true;

           

            /*

                         * Open the environment. Any errors will be caught

                         * by the caller.

                         */

            env = BerkeleyDB.DatabaseEnvironment.Open(directory, envCfg);

 

            /*

             * Open the database. Do not provide a txn handle. This

             * Open is autocommitted because BTreeDatabaseConfig.AutoCommit

             * is true.

             */

            dbCfg.Env = env;

            db = BerkeleyDB.BTreeDatabase.Open(dbName, dbCfg);

            txn = env.BeginTransaction();

        }

 

        public void TearDownEnv()

        {

            /* Remove environment regions. */

           try

            {

                BerkeleyDB.DatabaseEnvironment.Remove(directory);

            }

            catch

            {

                throw;

            }

        }

 

        public void Dispose()

        {

            if (!iscomit)

                Commit();

        }

        private void Reset()

        {

            iscomit = false;

        }

        private bool iscomit = false;

        public void Commit()

        {

            if (txn != null)

            {

                txn.Commit();

                txn = null;

            }

            iscomit = true;

        }

 

 

        public void Set(IPut put)

        {

            Set<IPut>(put.Key, put);

        }

        public void Set<T>(string aKey, T aData)

        {

            Reset();

            BinaryFormatter formatter = new BinaryFormatter();

            MemoryStream ms = new MemoryStream();

 

            BerkeleyDB.DatabaseEntry key = new BerkeleyDB.DatabaseEntry();

            dbtFromString(key, aKey);

 

            formatter.Serialize(ms, aData);

 

            Byte[] bytes = ms.GetBuffer();

            BerkeleyDB.DatabaseEntry data = new BerkeleyDB.DatabaseEntry(bytes);

 

            // Put key/data pair within the transaction.

            db.Put(key, data, txn);

        }

        public void Remove(IPut put)

        {

            Remove(put.Key);

        }

        public void Remove(string aKey)

        {

            BerkeleyDB.DatabaseEntry key = new BerkeleyDB.DatabaseEntry();

            dbtFromString(key, aKey);

            db.Delete(key, txn);

        }

        public void Get<T>(ref T put) where T : IPut

        {

            put = Get<T>(put.Key);

        }

 

        public T Get<T>(string aKey)

        {

            Reset();

            BerkeleyDB.DatabaseEntry key = new BerkeleyDB.DatabaseEntry();

            dbtFromString(key, aKey);

            KeyValuePair<BerkeleyDB.DatabaseEntry, BerkeleyDB.DatabaseEntry> pair = db.Get(key, txn);

 

            BinaryFormatter formatter = new BinaryFormatter();

            MemoryStream ms = new MemoryStream(pair.Value.Data);

 

            return (T)formatter.Deserialize(ms);

        }

       

        public void dbtFromString(BerkeleyDB.DatabaseEntry dbt, string s)

        {

            dbt.Data = System.Text.Encoding.ASCII.GetBytes(s);

        }

 

        public string strFromDBT(BerkeleyDB.DatabaseEntry dbt)

        {

 

            System.Text.ASCIIEncoding decode = new ASCIIEncoding();

            return decode.GetString(dbt.Data);

        }

 

        /*

         * Delete existing test output directory and its files,

         * then create a new one.

         */

        public static void ClearDir(string testDir)

        {

            if (Directory.Exists(testDir))

                Directory.Delete(testDir, true);

            Directory.CreateDirectory(testDir);

        }

    }

 

 

简单做了几种 几种添加  支持可序列化的任何对性 提供了泛型接口

如:

添加

using (BDB4_8Manager manager = new BDB4_8Manager())

            {

                Dictionary<string, Dictionary<string, Item>> dic = new Dictionary<string, Dictionary<string, Item>>();

                Dictionary<string, Item> dic2 = new Dictionary<string, Item>();

                for (int i = 0; i < 10; i++)

                {

                    Item _item = new Item();

                    _item.ID = i;

                    _item.Name = i + "Name";

                    _item.Text = i + "Text";

                    dic2.Add(i + "key", _item);

                }

                dic.Add("dickey", dic2);

                manager.Set < Dictionary<string, Dictionary<string, Item>>>("key", dic);

 

            }

 

 

读取

using (BDB4_8Manager manager = new BDB4_8Manager())

            {

                Dictionary<string, Dictionary<string, Item>> dic;

                dic = manager.Get < Dictionary<string, Dictionary<string, Item>>>("key");

            }

 

删除

 

manager.Remove(“Key”);

 

 

 

 

posted on 2009-10-29 15:56  zhuyonghui  阅读(863)  评论(1)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3