计算机理论论文开源世界里的面向对象数据库db4o
所属栏目:计算机应用论文
发布时间:2013-11-12 16:44:21 更新时间:2013-11-12 16:01:20
摘要:介绍了开源的,面向对象数据库db4o的优点及特性,通过c#语言展示其如何在程序设计中使用和操作。细致讲解db4o如何对数据库中的对象进行基本的加载,更新,删除操作及其三种十分重要的查询方式。
关键词:面向对象数据库,db4o,开源,程序设计
1引言
面向对象是一种认识方法学,也是一种新的程序设计方法学。把面向对象的方法和数据库技术结合起来可以使数据库系统的分析、设计最大程度地与人们对客观世界的认识相一致。面向对象数据库系统是为了满足新的数据库应用需要而产生的新一代数据库系统。
这里要介绍的db4o数据库就是一种Java,.NET及Mono原生的性能卓越的纯面向对象的开源的数据库引擎,由来自加州硅谷的开源面向对象数据库公司db4objects开发研制。对于Java与.NET开发者来说都是一个简单易用的对象持久化工具,使用简单,你只需要在你的项目中加入db4o.dll的引用即可。目前一些世界级的领导厂商如Inter,IBM,Bosch,BMW,Seagate,Hertz等都是它的客户。
b4o的目标是提供一个适合嵌入的功能强大的数据库引擎,用以工作在移动设备,桌面以及服务器等各种平台。其主要特性如下:
开源模式:与其他ODBMS不同,db4o为开源软件。
原生数据库:db4o是100%的原生的面向对象数据库,直接使用编程语言来操作数据库。程序员无需进行OR映射来存储对象,大大节省了程序员在存储数据的开发时间。
高性能:db4o安装简单占空间小,仅需要400Kb左右。在db4o官方公布的基准测试数据中,db4o比采用Hibernate/MySQL方案在某些测试线路上速度高出44倍之多。
零管理:使用db4o无需DBA。
db4o支持Java和.Net平台。
2设计类实例
在对db4o数据库的特点和特性有了大致了解后,我们通过一个例子来介绍db4o数据库在程序设计中的使用。事例语言为C#语言,这个例子展示如何存储、更新、加载、删除一个只包括系统内置类型及字符串成员的简单对象实例,这个对象是一个存储了学生(Student)的相关信息如姓名及本学期所取得学分的类。
publicclassStudent
{privatestring_name;
privateint_points;
publicStudent(stringname,intpoint)
{_name=name;
_points=points;}
publicstringname
{get{return_name;}
set{_name=value;}}
publicintpoints
{get{return_points;}
set{_points=value;}}
publicvoidAddPoints(intpoints)
{points+=points;}
overridepublicstringToString()
{returnstring.Format("{0}/{1}",_name,_points);}}
3打开关闭数据库
使用Db4o.OpenFile()函数打开或新建一个db4o数据库,Db4o.OpenFile()需要一个参数作为特定路径的文件名,以此来获得特定的ObjectContainer实例——ObjectContainer对外就是一个数据库,也是我们操作db4o的主要接口。关闭ObjectContainer使用Close()函数,它将会关闭数据库文件并释放其占用的系统资源。
ObjectContainerdb=Db4o.OpenFile(FilePathName);
try
{//Youcandosomethinghere}
finally
{db.Close();}
此处db作为下文引用和存储数据库文件的变量名,其打开和关闭数据库的操作后面将不再写出。
4保存对象
当我们想保存一个对象时,我们只需要简单的调用db4o的Set()方法,并传入要保存的对象作为参数即可。比如向db4o数据库存入一个姓名为“Liming”,学分是86的学生对象。代码如下:
Studentstu=newStudent("Liming",86);
db.Set(stu);
Console.WriteLine("Student{0}",stu.Tostring());
5加载对象
db4o提供了三种不同的查询数据的方法,(1)QBE:通过实例查询;(2)NQ:db4o原生/本地化查询;(3)SODA:一种通过数据库持久层进行的查询,查询语句被定义在字符串中,并通过持久引擎进行解释执行。其中NQ是db4o推荐使用的查询方式。这是因为NQ方式提供了非常强大的查询功能,支持原生语言,也就意味着你可以使用Java,.net来判断该对象是否符合条件,这是其他数据库查询语言无法比拟的。在某些情况下,db4o核心会将NQ翻译成SODA以获得更高的性能。
这下面分别详细介绍一下这三种查询语言。
5.1QBE查询
当使用QBE进行查询时,我们需要为希望加载的数据而创建一个对象原型(prototypical),db4o将会加载所有与原型相同类型(各成员字段不为默认值)的对象,返回的结果将会存储在ObjectSet对象实例中。
这如果想要从数据库中加载所有的学生对象,我们要提供了一个初始值为空的Student原型对象。原型对象中车手的积分为0,这是因为对于int型字段的默认值为0。
Studentstu=newStudent(null,0);
ObjectSetresult=db.Get(stu);
foreach(objectiteminresult)
{Console.WriteLine("Student{0}",stu.Tostring());}
如果我们想要从数据库中加载特定的学生对象,只需要相应提供给数据库你所需要的信息即可。比如想得到姓名为“Liming”,学分值是80的学生对象:
Studentstu=newStudent("Liming",80);
ObjectSetresult=db.Get(stu);
foreach(objectiteminresult)
{Console.WriteLine("Student{0}",stu.Tostring());}
通过上面的例子我们不难看出,使用QBE方式进行查询存在着如下几个局限点:
1)db4o需要反射你提供模板对象的所有成员数据;
2)不能使用高级查询表达式,如AND、OR、NOT等;
3)对于数据不能使用强制条件,如int的0,string的空字串或空引用类型,因为它们在查询时都解释为非强制关系;
需要为类提供非初始化成员数据的构造函数,这意味着在定义数据成员时不能对其进行初始化。
所以,我们推荐的是另一种查询方式NQ。
5.2NQ查询
使用NQ为你的查询提供了开发语言内置的支持能力,提供类型安全机制、编译时检查及反射功能,使用面向对象的方法调用来完成查询。NQ是db4o数据库查询的主要接口也是开发者极力推荐的数据查询方式,因为NQ充分运用了开发语言的语义完整性,将会成为将来完美而安全的选择。
这也有人说使用NQ查询就是用你熟悉的编程语言进行数据库查询。所以这样写出的查询代码将是100%的类型安全、100%的编译时检查以及100%的可重构。
下面我们看看在C#语言中NQ是如何进行使用的。
C#.NET2.0
Iliststu=db.Query(delegate(Studentstu){
returnStu.points=80;});
C#.NET1.1
IListlist=db.query(newStudentPoints());
publicclassStudentPoints:Predicate{
{publicbooleanmatch(Studentstu)
{returnstu.Points=80;}};
for(intx=0;x
{Console.Writeline(list.get(x));}
从上述代码中可以看出,对于不支持泛型的语言来说,都需要提供一个扩展com.db4o.Predicate的类,并提供一个参数为待查询的类,并返回布尔值的函数#.Match()或#.match(),其函数签名为:
boolMatch(Pilotcandidate);
可以看到,在进行NQ查询时并没有加入任何条件(无条件返回true),那么这么做是不是相当于遍历了整个数据库?db4o的设计者早就想到了这个问题,当db.query()执行完毕返回list实例的时候,db4o只是与数据库同步取出内部的IDs而已,并没有把所有的Student对象全部取出,只有在list.get(x)之后才会去根据IDs取出记录。所以我们不必担心性能方面的问题。
5.3SODA查询
SODA是db4o提供的底层查询接口,允许开发人员直接操作查询表达式树中的节点,它采用字符串标识对象数据成员,但是这种方式既不是类型安全也不在编译时进行检查并且写起来十分冗长。
比如我们想查找成绩在80到90分之间,或者姓名为“Liming”的对象。用NQ查询代码如下:
IListresult=db.Query(delegate(Studentstu){
returnstu.Points>80
&&stu.Points<90
||stu.Name=="Liming";});
而用SODA写起来则较麻烦一些:
Queryquery=db.Query();
query.Constrain(typeof(Student));
QuerypointQuery=query.Descend("_points");
query.Descend("_name").Constrain("Liming")
.Or(pointQuery.Constrain(80).Greater()
.And(pointQuery.Constrain(90).Smaller()));
ObjectSetresult=query.Execute();而SODA也有其它两种查询不可比拟的优势,那就是使你的应用程序能够动态生成查询,这种情况也是我们在应用开发中所需要的。
看一看由QBE查询转换为SODA的例子,想得到所有车手的对象信息,对于查询的约束为Student类对象。
Queryquery=db.Query();
query.Constrain(typeof(Student));
ObjectSetresult=query.Execute();
ListResult(result);
为了通过学生姓名字进行查询,我们需要扩展上述约束条使其包含待查询对象的”name”字段的相应字符串。
Queryquery=db.Query();
query.Constrain(typeof(Student));
query.Descend("_name").Constrain("Liming");
ObjectSetresult=query.Execute();
ListResult(result);
现在对db4o数据库的查询工作做一个总结。我们可以通过其提供的三种方式中的任意一种来完成。对于何时采用哪种方式进行查询,我们的建议是:
(1)NQ作为db4o主要的查询接口将是我们不二的首选;
(2)当前版本中对NQ查询的优化操作总是以SODA方式来执行的,因此SODA可以作为系统优化的一种途径,同时它总是用来在运行时动态的生成查询。
(3)QBE对于初学者来说将是很好的选择,当然它在功能上会有些限制,如果你喜欢的话有时对的应用还是很适合的。
6更新对象
更新对象跟存储它们一样简单,实际上我们只需要把更改后的对象在存入数据库中就可以了。即再次调用同样的方法Set()方法就可以了。
ObjectSetresult=db.Get(newStudent("Liming",0));
Studentstu=(Student)result.Next();
stu.AddPoints(11);
db.Set(found);
Console.WriteLine("Added11pointsfor{0}",stu.ToString());
请注意,在调用Set()方法更新对象之前我们先进行了查询,这一点十分重要。这是因为如果在当前的存储或加载操作过程所处的会话中对象对于db4o不可知的话,db4o将会向数据库中插入一个新的对象,之所以会这样是因为db4o不会自动的去匹配先前存储于数据库的对象,而是假设你向数据库中存入第二个拥有相同属性的对象。
7删除对象
删除数据库中的对象使用的方法是Delete()方法。
ObjectSetresult=db.Get(newStudent("Liming",0));
Studentstu=(Student)result.Next();
db.Delete(stu);
8结语
Db4o面向对象数据库与传统数据模型相比较,优势体现在:一是Db4o对数据语义的扩展更大,通过允许定义任何复杂的数据类型和提供与数据相关联的行为。这种语义更接近于面向对象程序设计语言的语义。二是面向对象技术强调与数据相关的软件的组织而不是强调控制流,从而把程序员的注意力转向数据库设计者的意图,面向对象语言和面向对象数据库相互形成互补,并且又保持了各自的长处。三是Db4o在功能方面与关系数据库有很大的区别。关系数据库,如SQLSever在运行时根据存在表中的数据集而导出一个虚结构。Db4o数据库本身含有对象。四是Db4o是一种主动型数据库,而一个关系数据库则是被动型的数据库。关系数据库主要提供的是增删记录的能力,而面向对象数据库提供了在对象中嵌入方法的能力。因而,Db4o数据库可以嵌入很多的操作,而在关系数据库中,这些操作需要应用程序来实现。五是Db4o新引入的抽象、扩充类型定义、用户自定义操作以及支持版本规模型演化等概念和功能,消除了传统数据库对数据定义的一致性,提供了更为丰富的语义。
参考文献:
[1]Object-orienteddatabaseprogrammingwithdb4o[EB/OL].http://anf.hidotnet.com/30878/ShowPost/
[2]DB4O国内翻译的部分资料——Asp.NetForums[EB/OL].http://hidotnet.com/PrintThread/?PostID=30860
[3]王意洁编著.面向对象的数据库技术[M].电子工业出版社,2005
注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文。
月期刊平台服务过的文章录用时间为1-3个月,依据20年经验,经月期刊专家预审通过后的文章,投稿通过率100%以上!