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) 收藏 举报
浙公网安备 33010602011771号