让我们以一个简单的例子作为db4o之旅的开始,通过这个例子展示如何存储、更新、加载以及删除一个只包括系统内置类型及字符串成员的简单对象实例,这个对象是一个存储了F1车手(Pilot)的相关信息如姓名及本赛季所取得积分的类。
首先我们将创建一个类来存储这些信息,它看上去像这样:
1
namespace
com.db4o.f1.chapter1
2
{
3 public class Pilot
4 {
5 string _name;
6 int _points;
7
8 public Pilot(string name, int points)
9 {
10 _name = name;
11 _points = points;
12 }
13
14 public string Name
15 {
16 get
17 {
18 return _name;
19 }
20 }
21
22 public int Points
23 {
24 get
25 {
26 return _points;
27 }
28 }
29
30 public void AddPoints(int points)
31 {
32 _points += points;
33 }
34
35 override public string ToString()
36 {
37 return string.Format("{0}/{1}", _name, _points);
38 }
39 }
40}
41
请注意:在类定义的代码中没有包含任何db4o相关的代码。
2.1、打开数据库
为打开已有的或新建一个db4o数据库我们使用Db4o.OpenFile()函数,并为其传入一个特定路径的文件名作为参数,以此来获得特定的ObjectContainer实例。ObjectContainer对外就是一个数据库,也是我们操作db4o的主要接口。关闭ObjectContainer使用#.Close()函数,它将会关闭数据库文件并释放其占用的系统资源。
1
[accessDb4o]
2
ObjectContainer db
=
Db4o.OpenFile(Util.YapFileName);
3
try
4
{
5 // do something with db4o
6}
7
finally
8
{
9 db.Close();
10}
在接下来的例子中假设我们的环境有一个变量"db"来引用和存储数据库文件Util.YapFileName,并会在需要的时候自动的打开或关闭数据库。
2.2、保存对象
为了保存对象我们只需要在数据库对象上简单的调用Set()方法并传入适当的参数即可。
1
[storeFirstPilot]
2
Pilot pilot1
=
new
Pilot(
"
Michael Schumacher
"
,
100
);
3
db.Set(pilot1);
4
Console.WriteLine(
"
Stored {0}
"
, pilot1);
好,我们再存入第二个车手对象。
1
[storeSecondPilot]
2
Pilot pilot2
=
new
Pilot(
"
Rubens Barrichello
"
,
99
);
3
db.Set(pilot2);
4
Console.WriteLine(
"
Stored {0}
"
, pilot2);
2.3、加载对象
db4o提供了三种不同的查询数据的方法,(1)、通过实例查询(QBE);(2)、db4o原生/本地化查询(NQ);(3)、SODA查询接口(SODA是一种通过数据库持久层进行的查询,查询语句被定义在字符串中,并通过持久引擎进行解释执行)。在这一节的例子中我将仅介绍QBE,而在日常的开发中你将对象存储在数据库中后,我们推荐使用db4o主要的查询接口NQ进行查询。
当使用QBE进行查询时,我们需要为希望加载的数据而创建一个对象原型(prototypical ),db4o将会加载所有与原型相同类型(各成员字段不为默认值)的对象,返回的结果将会存储在ObjectSet对象实例中,我们使用一个"listResult"的函数来显示返回结果。
1
public
static
void
ListResult(ObjectSet result)
2
{
3 Console.WriteLine(result.Count);
4 foreach (object item in result)
5 {
6 Console.WriteLine(item);
7 }
8}
为了从数据库中加载所有的车手对象,我们提供了一个初始值为空的Polit原型对象。
1
[retrieveAllPilotQBE]
2
Pilot proto
=
new
Pilot(
null
,
0
);
3
ObjectSet result
=
db.Get(proto);
4
ListResult(result);
请注意在提供的原型对象中车手的积分为0,而实际返回的车手对象中则没有包含积分为0的对象,这是因为对于int型字段的默认值为0。
db4o也提供了一种便捷的方法来加载这些对象:
1
[retrieveAllPilots]
2
ObjectSet result
=
db.Get(
typeof
(Pilot));
3
ListResult(result);
在.NET 2.0中则可以通过泛型来处理:
IList
<
Pilot
>
pilots
=
db.query
<
Pilot
>
(
typeof
(Pilot));
以下示例则是通过车手的名字或特定的积分来加载车手对象:
1
[retrievePilotByName]
2
Pilot proto
=
new
Pilot(
"
Michael Schumacher
"
,
0
);
3
ObjectSet result
=
db.Get(proto);
4
ListResult(result);
5
6
//
And to query for Pilots with a specific number of points:
7
8
[retrievePilotByExactPoints]
9
Pilot proto
=
new
Pilot(
null
,
100
);
10
ObjectSet result
=
db.Get(proto);
11
ListResult(result);
12
在db4o中还有其它的一些查询方法,这将在以后的章节中深入的介绍。
2.4、更新对象
更新对象跟存储它们一样简单,实际上我们只需要在修改对象后再次调用同样的方法Set()就可以了。
1
[updatePilot]
2
ObjectSet result
=
db.Get(
new
Pilot(
"
Michael Schumacher
"
,
0
));
3
Pilot found
=
(Pilot)result.Next();
4
found.AddPoints(
11
);
5
db.Set(found);
6
Console.WriteLine(
"
Added 11 points for {0}
"
, found);
7
RetrieveAllPilots(db);
请注意,在调用Set()方法更新对象之前我们先进行了查询,这一点十分重要。如果在当前的存储或加载操作过程所处的会话中对象对于db4o不可知的话,db4o将会向数据库中插入一个的对象,之所以会这样是因为db4o不会自动的去匹配先前存储于数据库的对象,而是假设你向数据库中存入第二拥有相同属性的对象。
为了验证数据库是否确实更新的车手信息,可以执行上面加载数据库对象的方法。
2.5、更新对象
删除数据库中的对象使用Delete()方法:
1
[deleteFirstPilotByName]
2
ObjectSet result
=
db.Get(
new
Pilot(
"
Michael Schumacher
"
,
0
));
3
Pilot found
=
(Pilot)result.Next();
4
db.Delete(found);
5
Console.WriteLine(
"
Deleted {0}
"
, found);
6
RetrieveAllPilots(db);
可以使用上面提供的加载对象的方法来验证其是否已经从数据库中真正的删除了。
在更新对象时,对象也将首先被db4o删除,这时提供一个原型对象将不足于进行相关的操作而必须提供一个完全匹配的对象给数据库。
2.6、小结
是不是很简单呢?只需要简单的几行代码就完成了对db4o数据库对象的保存、更新、加载及删除操作。而对于复杂的查询任务如何完成呢?我们将通过在下一章中介绍的含有约束条件的QBE查询完成。
以下是本单元的所有源代码:
完整的代码
1using System;
2using System.IO;
3using com.db4o;
4using com.db4o.f1;
5namespace com.db4o.f1.chapter1
6{
7 public class FirstStepsExample : Util
8 {
9 public static void Main(string[] args)
10 {
11 File.Delete(Util.YapFileName);
12 AccessDb4o();
13 File.Delete(Util.YapFileName);
14 ObjectContainer db = Db4o.OpenFile(Util.YapFileName);
15 try
16 {
17 StoreFirstPilot(db);
18 StoreSecondPilot(db);
19 RetrieveAllPilots(db);
20 RetrievePilotByName(db);
21 RetrievePilotByExactPoints(db);
22 UpdatePilot(db);
23 DeleteFirstPilotByName(db);
24 DeleteSecondPilotByName(db);
25 }
26 finally
27 {
28 db.Close();
29 }
30 }
31
32 public static void AccessDb4o()
33 {
34 ObjectContainer db=Db4o.OpenFile(Util.YapFileName);
35 try
36 {
37 // do something with db4o
38 }
39 finally
40 {
41 db.Close();
42 }
43 }
44
45 public static void StoreFirstPilot(ObjectContainer db)
46 {
47 Pilot pilot1 = new Pilot("Michael Schumacher", 100);
48 db.Set(pilot1);
49 Console.WriteLine("Stored {0}", pilot1);
50 }
51
52 public static void StoreSecondPilot(ObjectContainer db)
53 {
54 Pilot pilot2 = new Pilot("Rubens Barrichello", 99);
55 db.Set(pilot2);
56 Console.WriteLine("Stored {0}", pilot2);
57 }
58
59 public static void RetrieveAllPilotQBE(ObjectContainer db)
60 {
61 Pilot proto = new Pilot(null, 0);
62 ObjectSet result = db.Get(proto);
63 ListResult(result);
64 }
65
66 public static void RetrieveAllPilots(ObjectContainer db)
67 {
68 ObjectSet result = db.Get(typeof(Pilot));
69 ListResult(result);
70 }
71
72 public static void RetrievePilotByName(ObjectContainer db)
73 {
74 Pilot proto = new Pilot("Michael Schumacher", 0);
75 ObjectSet result = db.Get(proto);
76 ListResult(result);
77 }
78
79 public static void RetrievePilotByExactPoints(ObjectContainer db)
80 {
81 Pilot proto = new Pilot(null, 100);
82 ObjectSet result = db.Get(proto);
83 ListResult(result);
84 }
85
86 public static void UpdatePilot(ObjectContainer db)
87 {
88 ObjectSet result = db.Get(new Pilot("Michael Schumacher", 0));
89 Pilot found = (Pilot)result.Next();
90 found.AddPoints(11);
91 db.Set(found);
92 Console.WriteLine("Added 11 points for {0}", found);
93 RetrieveAllPilots(db);
94 }
95
96 public static void DeleteFirstPilotByName(ObjectContainer db)
97 {
98 ObjectSet result = db.Get(new Pilot("Michael Schumacher", 0));
99 Pilot found = (Pilot)result.Next();
100 db.Delete(found);
101 Console.WriteLine("Deleted {0}", found);
102 RetrieveAllPilots(db);
103 }
104
105 public static void DeleteSecondPilotByName(ObjectContainer db)
106 {
107 ObjectSet result = db.Get(new Pilot("Rubens Barrichello", 0));
108 Pilot found = (Pilot)result.Next();
109 db.Delete(found);
110 Console.WriteLine("Deleted {0}", found);
111 RetrieveAllPilots(db);
112 }
113 }
114}
115