Tips:这两天在看db4o tutorial,照着
http://wiki.redsaga.com/confluence/pages/viewpage.action?pageId=2137上JAVA文档的翻译,.net的就差不多了,顺便也整理了一下,后面继续把相关内容整理。
欢迎
db4o是原生的Java,.NET和Mono的开源对象数据库.
写这份指南是为了使你能够对db4o尽快上手。在你开始之前,请首先确保你已经从db4objects的网站上下载了最新的db4o发行包。
developer.db4o.com
你被邀请加入db4o社区的公共论坛,在那里可以随时请求帮助。同时请尝试一下db4o知识库的关键词搜索功能。
链接
这里是developer.db4o.com上的一些深入学习的链接,你可能会觉得有用:
All Downloads
Release Note Blog
SVN Access
Design Wiki
Community Projects
下载的内容
db4o的Java发布版本是以一个MSI安装文件(db4o-7.4-net.msi)的形式进行发布的。安装这个文件后,你将获得下面的目录结构:
请看一下所有的文档格式,选择一个最适合你的:
db4o-7.4/doc/api/db4o.chm
db4o的API文档以编译的Chm文件格式提供。当你阅读这份指南的时候,偶尔翻阅一下这个API文档是很有帮助的。
db4o-7.4/doc/reference/index.html
参考文档是对有经验的db4o用户来说是一个完整的编辑物。它以在线的方式维护。
db4o-7.4/doc/tutorial/Db4objects.Db4o.Tutorial.exe
交互式指南的.net应用程序。示例可以依靠一个db4o数据库在该应用程序上实时运行。如果你在使用交互功能的时候遇到了问题,请参考指南的交互式指南故障排除部分。
db4o-7.4/doc/tutorial/db4o-7.4-tutorial.pdf
这份PDF版本的指南很好的支持全文检索功能。
1. 第一印象
在讲解第一个示例代码之前,我们先了解一些必要的基础知识。
do4o对象数据库引擎由一个DLL文件组成。你编程所需的引用都在里面。你可以在/db4o-7.0/lib/找到所发布版本。
db40 For .net 有多个可用的发布版本。一是支持.NET Framework 1.0/1.1的可下载版本,而另一个是支持.NET Framework 2.0的可下载版本。请确定为你的开发环境下载了正确的版本。
/db4o-7.4/bin/net-2.0/Db4objects.Db4o.dll
.NET 2.0 framework平台的db4o引擎。
/db4o-7.4/bin/compact-2.0/Db4objects.Db4o.dll
.NET 2.0 CompactFramework平台的db4o引擎。
/db4o-7.4/bin/net-3.5/Db4objects.Db4o.dll
.NET 3.5 framework平台的db4o引擎。
/db4o-7.4/bin/compact-3.5/Db4objects.Db4o.dll
.NET 3.5 CompactFramework平台的db4o引擎。
1.2. 安装
要在一个项目中使用db4o,你只要在项目中添加对上面相应Db4objects.Db4o.dll 的引用就可以了。
1.3. API 概况
请在阅读本指南的时候,不要忘记API文档。它按照命名空间提供了有组织的API视图,你可以在阅读本指南的同时使用它方便地找到与阅读主题相关的功能。
首先,Db4objects.Db4o 、Db4objects.Db4o.Query 命名空间是我们所需要关心的。
Db4objects.Db4o
Db4objects.Db4o 命名空间包含了几乎所有通常所需要用到的功能。其中有两个值得留意的类:Db4objects.Db4o.Db4oFactory 和Db4objects.Db4o.IObjectContainer。
- IObjectContainer 可以作为单用户模式的数据库,也可以作为db4o服务器的客户端连接。
- 每个IObjectContainer 持有一个事务,所有的操作都是事务相关的。 当你打开一个IObjectContainer时 ,事务已经开始了,当你commit()或者rollback(),它将会马上启动下一个事务。
- 每个IObjectContainer 会自己管理那些被其存储并实例化的对象的引用。而做这些工作的同时,它还管理这对象的唯一标识,这样是它能够达到很高的性能。
- 在使用IObjectContainer 的过程中,只要你还在使用它,它就会一直保持打开状态。而当你关闭这个ObjectContainers时,所有保存在内存中的对象引用都将被丢弃掉。
Db4objects.Db4o.Ext
也许你会问为什么IObjectContainer里面只有那么少的方法,原因是将db4o接口被分别放置在Db4objects.Db4o 和Db4objects.Db4o.Ext 这两个命名空间中,这么做是为了:
- 便于快速开始,因为重要的方法都在ObjectContainer中被强调了。
- 其他产品更容易复制db4o的基本接口。
- 很好地展现了一个db4o的轻量级版本。
每个IObjectContainer 对象同时也是一个IExtObjectContainer对象。你可以把它转换成IExtObjectContainer,或者可以使用.Ext() 方法来获得更高级的特性。
Db4objects.Db4o.Config
Db4objects.Db4o.Config 命名空间里面包含了配置db4o所需的类型和类,我们将在配置章节中讨论它的对象和接口。
Db4objects.Db4o.Query
Db4objects.Db4o.Query 包中包含了用来构造原生查询的Predicate类。Native Query接口是db4o最主要的查询接口,并且它应该比Soda查询API更常用。
2. 第一步
让我们尽量简单地开始。我们将演示用db4o如何存储,读取,更新和删除一个类的实例,这个类只包含基本类型和String类型的成员变量。在我们的例子中就是F1赛车手的名字和他在这个赛季获的得分。
首先创建一个类来保存我们的数据。代码示例如下:

Code
namespace Db4objects.Db4o.Tutorial.F1.Chapter1


{
public class Pilot

{
string _name;
int _points;
public Pilot(string name, int points)

{
_name = name;
_points = points;
}
public string Name

{
get

{
return _name;
}
}
public int Points

{
get

{
return _points;
}
}
public void AddPoints(int points)

{
_points += points;
}
override public string ToString()

{
return string.Format("{0}/{1}", _name, _points);
}
}
}

注意这个类中没有包含任何和db4o有关的代码。
2.1. 打开数据库
要访问或新建一个db4o数据库文件,把文件存储路径作为参数调用Db4oFactory.OpenFile()方法获取一个IObjectContainer 实例。IObjectContainer 就代表"数据库",它将是你操作db4o的主要接口。调用#close()方法来关闭IObjectContainer ,这样做也将关闭数据库文件并且释放所有关联的资源。
// accessDb4o
IObjectContainer db = Db4oFactory.OpenFile(Util.YapFileName);
try
{
// do something with db4o
}
finally
{
db.Close();
}
下面的例子我们将假定由环境来自动管理IObjectContainer 的打开,关闭,以'db'为变量名保存其引用。
2.2. 存储对象
要保存对象,只需在数据库上调用Store()方法,以任意对象为参数传入即可。
// storeFirstPilot
Pilot pilot1 = new Pilot("Michael Schumacher", 100);
db.Store(pilot1);
Console.WriteLine("Stored {0}", pilot1);
我们还需要一个赛车手,做法一样。
// storeSecondPilot
Pilot pilot2 = new Pilot("Rubens Barrichello", 99);
db.Store(pilot2);
Console.WriteLine("Stored {0}", pilot2);
2.3. 检索对象
Db4o提供三种不同的查询机制,样本查询(QBE),原生查询(NQ)和SODA查询接口(SODA)。在第一个例子中我们将介绍如何使用QBE。如果你对存储对象比较熟悉,我们推荐你使用原生查询,它是db4o主要的查询接口。
在使用QBE时,你要创建一个原型对象作为你要读取对象的样本。db4o会读取所有指定类型的对象,这些对像含有与样本一样(并非缺省)的属性值。结果以IObjectSet 实例的形式返回。我们将使用一个便捷的方法#ListResult()来显示查询结果对象集中的内容。
public static void ListResult(IObjectSet result)
{
Console.WriteLine(result.Count);
foreach (object item in result)
{
Console.WriteLine(item);
}
}
要从数据库获取所有赛车手,我们可以给一个空的原型:
// retrieveAllPilotQBE
Pilot proto = new Pilot(null, 0);
IObjectSet result = db.QueryByExample(proto);
ListResult(result);
注意我们设定分数为0,但是我们的查询结果并没有受此约束,因为0是int类型的缺省值。
db4o还提供一个快捷方式来获取一个类的所有实例:
// retrieveAllPilots
IObjectSet result = db.QueryByExample(typeof(Pilot));
ListResult(result);
.NET 2.0也有一个泛型快捷方式,这样使用query方法:
IList <Pilot> pilots = db.Query<Pilot>(typeof(Pilot));
使用名字查询赛车手,代码如下:
// retrievePilotByName
Pilot proto = new Pilot("Michael Schumacher", 0);
IObjectSet result = db.QueryByExample(proto);
ListResult(result);
使用给定的分数查询赛车手,代码如下:
// retrievePilotByExactPoints
Pilot proto = new Pilot(null, 100);
IObjectSet result = db.QueryByExample(proto);
ListResult(result);
当然db4o有很多种查询方式,我们将会在后续的章节中深入学习。
2.4. 更新对象
更新对象和存储对象一样容易,实际上,你使用相同的Store()方法去更新你的对象,在你修改任何对象后只需要再次调用Store就可以了。
// updatePilot
IObjectSet result = db.QueryByExample(new Pilot("Michael Schumacher", 0));
Pilot found = (Pilot)result.Next();
found.AddPoints(11);
db.Store(found);
Console.WriteLine("Added 11 points for {0}", found);
RetrieveAllPilots(db);
注意我们先查询得到要更新的对象,这点和重要。当你调用Store()去修改一个存储对象时,如果这个对象不是持久化对象(在前面已经存储过或者在当前会话中读取到的对象),db4o将会插入一个新对象。db4o这么做是因为它不会自动比较要存储的对象和先前存储过的对象。它认为你是想再存储一个属性值一样的对象。
要确认赛车手是否更新成功,请找到前面的任何一段读取的示例程序再运行一次即可。
2.5. 删除对象
使用Delete()方法,数据将被从数据库中删除。
// deleteFirstPilotByName
IObjectSet result = db.QueryByExample(new Pilot("Michael Schumacher", 0));
Pilot found = (Pilot)result.Next();
db.Delete(found);
Console.WriteLine("Deleted {0}", found);
RetrieveAllPilots(db);
我们再来删除另一个对象,
// deleteSecondPilotByName
IObjectSet result = db.QueryByExample(new Pilot("Rubens Barrichello", 0));
Pilot found = (Pilot)result.Next();
db.Delete(found);
Console.WriteLine("Deleted {0}", found);
RetrieveAllPilots(db);
运行前面读取的例子来验证删除是否成功。
和更新对象一样,要删除的对象也必须是持久对象,只是提供一个属性值一样的对象是不可以成功删除的。
2.6. 结论
是不是很简单呀?我们只需要简单的几行代码就可以存储,读取,更新和删除对象。但是对于复杂的查询呢?下一章我们将了解QBE的不足和其它可用的查询方法。
2.7. 完整代码

Code
using System;
using System.IO;
using Db4objects.Db4o.Query;
using Db4objects.Db4o.Tutorial;
namespace Db4objects.Db4o.Tutorial.F1.Chapter1


{
public class FirstStepsExample : Util

{
public static void Main(string[] args)

{
File.Delete(Util.YapFileName);
AccessDb4o();
File.Delete(Util.YapFileName);
IObjectContainer db = Db4oFactory.OpenFile(Util.YapFileName);
try

{
StoreFirstPilot(db);
StoreSecondPilot(db);
RetrieveAllPilots(db);
RetrievePilotByName(db);
RetrievePilotByExactPoints(db);
UpdatePilot(db);
DeleteFirstPilotByName(db);
DeleteSecondPilotByName(db);
}
finally

{
db.Close();
}
}
public static void AccessDb4o()

{
IObjectContainer db = Db4oFactory.OpenFile(Util.YapFileName);
try

{
// do something with db4o
}
finally

{
db.Close();
}
}
public static void StoreFirstPilot(IObjectContainer db)

{
Pilot pilot1 = new Pilot("Michael Schumacher", 100);
db.Store(pilot1);
Console.WriteLine("Stored {0}", pilot1);
}
public static void StoreSecondPilot(IObjectContainer db)

{
Pilot pilot2 = new Pilot("Rubens Barrichello", 99);
db.Store(pilot2);
Console.WriteLine("Stored {0}", pilot2);
}
public static void RetrieveAllPilotQBE(IObjectContainer db)

{
Pilot proto = new Pilot(null, 0);
IObjectSet result = db.QueryByExample(proto);
ListResult(result);
}
public static void RetrieveAllPilots(IObjectContainer db)

{
IObjectSet result = db.QueryByExample(typeof(Pilot));
ListResult(result);
}
public static void RetrievePilotByName(IObjectContainer db)

{
Pilot proto = new Pilot("Michael Schumacher", 0);
IObjectSet result = db.QueryByExample(proto);
ListResult(result);
}
public static void RetrievePilotByExactPoints(IObjectContainer db)

{
Pilot proto = new Pilot(null, 100);
IObjectSet result = db.QueryByExample(proto);
ListResult(result);
}
public static void UpdatePilot(IObjectContainer db)

{
IObjectSet result = db.QueryByExample(new Pilot("Michael Schumacher", 0));
Pilot found = (Pilot)result.Next();
found.AddPoints(11);
db.Store(found);
Console.WriteLine("Added 11 points for {0}", found);
RetrieveAllPilots(db);
}
public static void DeleteFirstPilotByName(IObjectContainer db)

{
IObjectSet result = db.QueryByExample(new Pilot("Michael Schumacher", 0));
Pilot found = (Pilot)result.Next();
db.Delete(found);
Console.WriteLine("Deleted {0}", found);
RetrieveAllPilots(db);
}
public static void DeleteSecondPilotByName(IObjectContainer db)

{
IObjectSet result = db.QueryByExample(new Pilot("Rubens Barrichello", 0));
Pilot found = (Pilot)result.Next();
db.Delete(found);
Console.WriteLine("Deleted {0}", found);
RetrieveAllPilots(db);
}
}
}