面向 Java 开发人员的 db4o 指南Word文档下载推荐.docx
- 文档编号:16229267
- 上传时间:2022-11-21
- 格式:DOCX
- 页数:97
- 大小:87.88KB
面向 Java 开发人员的 db4o 指南Word文档下载推荐.docx
《面向 Java 开发人员的 db4o 指南Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《面向 Java 开发人员的 db4o 指南Word文档下载推荐.docx(97页珍藏版)》请在冰豆网上搜索。
与此同时,关系数据库已风光不再,一种新的数据库——对象数据库——成为了人们的新宠。
若能再结合一种面向对象的语言,例如C++(或与之类似的编程新贵,Java编程),OODBMS真是可以堪称编程的理想王国。
但是,事情的发展并非如此。
OODBMS在90年代晚期达到了顶峰,随后就一直在走下坡路。
原来的辉煌早已退去,剩下的只有晦涩和局限。
在第二轮的数据库之战结束之时,关系数据库又成了赢家。
(虽然大多数RDBMS供应商都或多或少地采用了对象,但这不影响大局。
)
上述情况中存在的惟一问题是,开发人员对OODBMS的热衷一直没有衰退,db4o的出现就很好地说明了这一点。
对象和关系
对象关系型阻抗失配这个话题完全可以拿出来进行学术讨论,但简单说来,其本质是:
对象系统与关系系统在如何处理实体之间的互动方面所采取的方式是截然不同的。
表面上看,对象系统和关系系统彼此非常合适,但若深入研究,就会发现二者存在本质差异。
首先,对象具有身份的隐式性质(其表征是隐藏/隐式的this指针或引用,它实际上是内存的一个位置),而关系则具有身份的显式性质(其表征是组成关系属性的主键)。
其次,关系数据库通过隐藏数据库范围内的数据查询和其他操作的实现进行封装,而对象则在每个对象上实现新的行为(当然,模块所实现的继承都在类定义中进行指定)。
另外,可能也是最有趣的是,关系模型是个封闭的模型,其中任何操作的结果都将产生一个元组集,适合作为另一个操作的输入。
这就使嵌套的SELECT以及很多其他功能成为可能。
而对象模型则无此能力,尤其是向调用程序返回“部分对象”这一点。
对象是要么全有要么全无的,其结果就是:
与RDBMS不同,OODBMS不能从表或一组表返回任一、全部或部分列。
简言之,对象(用像Java代码、C++和C#这类语言实现)和关系(由像SQLServer、Oracle和DB/2这样的现代RDBMS实现)操作的方式有极大的差异。
对于减少这种差异,程序员责无旁贷。
映射的作用
过去,开发人员曾试图减少对象和关系间的这种差距,尝试过的方式之一是手动映射,比如通过JDBC编写SQL语句并将结果收集进字段。
对这种方式的一个合理的质疑是:
是否还有更简化的方法来进行处理。
开发人员大都用自动的对象关系映射实用工具或库(比如Hibernate)来解决这个问题。
即使是通过Hibernate(或JPA、JDO、CastorJDO、Toplink或任何可用的其他ORM工具),映射问题也无法彻底解决,它们只会转移到配置文件。
而且,这种方式与要解决的问题颇有些风马牛不相及。
比方说,如果您想要创建一个分层良好的继承模型,将它映射到表或一组表无疑是失败之举。
若用对常规形式的违背来换取查询的性能,就会将DBA与开发人员在某种程度上对立起来。
可问题是很难构建一个富域模型(参见MartinFowler和EricEvans各自所著的书),不管是您以后想要调整它来匹配现有的数据库模式,还是想要调整数据库执行其操作的功能来支持对象模型(甚或这两者)。
但如果能不调整,岂不是更好?
进入db4o:
OODBMS的回归
db4o库是最近才出现在OODBMS领域的,它使“纯对象存储”的概念在新一代对象开发人员中重获新生。
(他们笑称,现在不是很流行怀旧么。
)为了让您对如何使用db4o有一个概念,特给出如下代表单个人的一个基本类:
注意:
如果还尚未下载,请现在就下载db4o。
为了更好地进行讨论(或至少编译代码),db4o是必需的,本系列的后续文章也会用到它。
清单1.Person类
packagecom.tedneward.model;
publicclassPerson
{
publicPerson()
{}
publicPerson(StringfirstName,StringlastName,intage)
{
this.firstName=firstName;
this.lastName=lastName;
this.age=age;
}
publicStringgetFirstName(){returnfirstName;
publicvoidsetFirstName(Stringvalue){firstName=value;
publicStringgetLastName(){returnlastName;
publicvoidsetLastName(Stringvalue){lastName=value;
publicintgetAge(){returnage;
publicvoidsetAge(intvalue){age=value;
publicStringtoString()
return
"
[Person:
+
firstName="
+firstName+"
lastName="
+lastName+"
age="
+age+
]"
;
publicbooleanequals(Objectrhs)
if(rhs==this)
returntrue;
if(!
(rhsinstanceofPerson))
returnfalse;
Personother=(Person)rhs;
return(this.firstName.equals(other.firstName)&
&
this.lastName.equals(other.lastName)&
this.age==other.age);
privateStringfirstName;
privateStringlastName;
privateintage;
}
在众多的类中,Person类显得极为寻常;
还很简单。
但若深入探究,就不难看出这个类会呈现出非常类似于对象的有趣属性和功能,例如它可以有配偶类,也可以有子类,等等。
(我在后续的专栏中会历数这些属性和功能;
现在,我只侧重于进行概括介绍。
)
在基于Hibernate的系统中,将这个Person类的一个实例放入数据库,需要如下几个步骤:
1.需要创建关系模式,向数据库描述类型。
2.需要创建映射文件,用这些文件将列和数据库的表映射到域模型的类和字段。
3.在代码中,需要通过Hibernate打开到数据库的连接(用Hibernate术语来说,就是会话),并与HibernateAPI进行交互来存储对象和将对象取回。
上述操作在db4o中出奇地简单,如清单2所示:
清单2.在db4o内运行INSERT
importcom.db4o.*;
importcom.tedneward.model.*;
publicclassHellodb4o
publicstaticvoidmain(String[]args)
throwsException
ObjectContainerdb=null;
try
db=Db4o.openFile("
persons.data"
);
Personbrian=newPerson("
Brian"
"
Goetz"
39);
db.set(brian);
mit();
finally
if(db!
=null)
db.close();
这样就行了。
无需生成模式文件,无需创建映射配置,需要做的只是运行客户机程序,当运行结束时,为存储在persons.data中的新“数据库”检查本地目录。
检索所存储的Person在某些方面非常类似于某些对象关系型映射库的操作方式,原因是对象检索最简单的形式就是按例查询(query-by-example)。
只需为db4o提供相同类型的一个原型对象,该对象的字段设置为想要按其查询的值,这样一来,就会返回匹配该条件的一组对象,如清单3所示:
清单3.在db4o内运行INSERT(版本1)
Personjason=newPerson("
Jason"
Hunter"
35);
Personclinton=newPerson("
Sletten"
38);
Persondavid=newPerson("
David"
Geary"
55);
Personglenn=newPerson("
Glenn"
Vanderberg"
40);
Personneal=newPerson("
Neal"
Ford"
db.set(jason);
db.set(clinton);
db.set(david);
db.set(glenn);
db.set(neal);
//FindalltheBrians
ObjectSetbrians=db.get(newPerson("
null,0));
while(brians.hasNext())
System.out.println(brians.next());
运行上述代码,会看到检索出两个对象。
回页首
但是...
在您将我定义为狂热的推崇者之前,请允许我先列举几条反对db4o的言论。
db4o几乎无法对应于现有的Oracle、SQLServer或DB2!
完全正确。
相比之下,db4o更适合于MySQL或HSQL,这使其对于大量项目来说已经足够。
更为重要的是,开销一直是db4o开发人员特别关注的事情,这又让它特别适于小型的嵌入式环境。
(我这里给出的示例只是一个简单的演示,和其他任何小型的演示一样,请务必清楚一点,即姑且不论它相比其他工具具有多少潜力,db4o都会比您在这里所看到的要强大许多。
我不能用JDBC在db4o上进行查询!
确实如此,尽管db4o团队曾想过创建JDBC驱动程序以让对象数据库能接受SQL语法,即一种所谓的“关系对象映射”。
(开发团队之所以没有这么做,据说是因为没有这个必要,而且性能会因此大受影响。
)问题的关键是,您在实现中使用的是对象(POJO),除此之外别无他物。
若不存储关系,为何还要使用SQL呢?
但是我的其他程序如何获得数据呢?
这要看具体情况。
如果您这里所谓的“其他程序”指的是其他Java代码,那么只需在这些程序内使用Person类的定义并将其传递进ObjectContainer,正如我这里所做的一样。
在OODBMS内,类定义本身就充当模式,所以无需其他的工具来获取Person对象。
但是如果您这里所谓的“其他程序”指的是其他语言的代码,那么问题就会复杂一些。
对于db4o不支持的语言,比如C++或Python,数据基本上是访问不到的,除非是您能从Java代码构建程序。
db4o适用于C#和其他的.NET语言,而其数据格式在二者之间是兼容的,这就使得Java对象对同样定义的.NET类也可用。
如果您这里所谓的“其他程序”指的是使用SQL和标准调用级接口(比如ODBC或JDBC)来与数据库进行交互的报告工具,那么db4o(或与此相关的任何OODBMS)可能未必是很好的选择。
机警的读者会发现报告功能现在对OODBMS还不可用,但好消息是:
已针对此问题发起很多产品和项目,而且db4o还支持“复制(Replication)”,它允许db4o实例将数据从其自身的存储格式复制进RDBMS。
但它是个文件!
在这种特殊情况下,确实如此;
但正如前面所讲,db4o在何处和如何存储数据方面十分灵活,而且还提供了一个轻量级的客户机/服务器选项。
如果您所期待的是功能完善的RDBMS所能提供的冗余性,那么db4o并不能如您所愿(但其他的OODBMS能提供这类特性)。
但当我再次运行示例时,我会得到副本!
(实际上,我每次运行该示例都会得到副本。
这里,实际上回到了我们所讨论的第一个有趣的问题:
身份,正是这一点将对象数据库和关系数据库区分开来。
正如我前面所言,对象系统中的身份是通过隐式的“this”引用赋予的,Java对象使用这个引用在内存中标识其自身。
在对象数据库中,它被称为OID(对象标识符),该OID在OODBMS中充当主键。
当创建新对象并将其“放”进数据库中时,新对象并不具有与其相关的OID,因而会收到其自身惟一的OID值。
它会复制,就如同RDBMS在执行每个INSERT操作时生成主键所做的那样(比如顺序计数器或自动增量字段)。
换言之,就主键而言,OODBMS与RDBMS相当接近,但主键本身并非传统RDBMS(或过去习惯使用RDBMS的程序员)认为的那种主键。
换言之,db4o旨在解决某些方面的问题,而不是成为解决全部持久性问题的一站式通用解决方案。
实际上,这让db4o首轮就战胜了OODBMS:
db4o无意向那些生产IT人员宣称自己是多么好的一种理念,以至于完全可以放弃他们在关系数据库上的投资。
结束语
传统的集中关系型数据库作为数据存储和操纵的首选工具的地位在短期内无法撼动。
以这种数据库为基础发展起来的工具非常之多,历史也很久远,而且许多程序员也都陷在“我们总需要数据库”的思维模式之中,这些无疑加固了其地位。
实际上,db4o在技术上的设计和定位并不是为了挑战RDBMS的这一地位。
但“面向服务”社区迫切要求我们构建松散耦合的多层世界,当您开始将OODBMS放到这种环境中去审视的时候,有趣的现象就出现了:
如果要实现组件(服务、层或诸如此类的东西)间真正的松散耦合,那么结果常常是某种程度的耦合只存在于服务的调用程序和该服务的公开API(或XML类型,不管您如何看待它)之间。
无需数据类型,无需公开对象模型,无需共享数据库——本质上讲,持久性方法仅仅是一个实现细节。
因此,在大量场景中可用的持久性方法的范围会显著扩大。
查询,更新和一致性
2007年4月20日
尽管RDBMS使用SQL作为其查询和检索数据的主要机制,但是OODBMS可以使用一些不同的机制。
在本系列的第二期文章中,TedNeward将介绍一些新方法,包括QuerybyExample以及定制只有OODBMS才具有的机制。
正如他解释的一样,有些替代方法比SQL本身更易于使用。
在本系列的第一篇文章中,我讨论了RDBMS作为Java™对象存储解决方案的不足之处。
正如我所说的,在当今的面向对象世界里,与关系数据库相比,db4o这样的对象数据库可以为面向对象开发人员提供更多的功能。
信息存储和检索作为同义语伴随RDBMS已经有10余年了,但现在情况有所改变。
Java开发人员为所谓的对象关系型阻抗失配而沮丧,也不再有耐心去尝试解决这个问题。
加上可行替代方案的出现,就导致了人们对对象持久性和检索的兴趣的复苏。
在本文及以后的文章中,我将继续介绍对象数据库。
我将使用示例来演示这种存储系统的强大之处,它尽可能实现与面向对象编程语言中(本例中为Java编程语言)使用的实体形式相同。
特别是,我将介绍用于检索、修改并将对象重新存储到db4o的各种可用机制。
正如您将了解的一样,当您从SQL的限制解脱出来后,会对自己能够完成这么多的事情而感到吃惊。
如果您还没有下载db4o,可能希望立即下载。
您需要使用它来编译示例。
QuerybyExample
QuerybyExample(QBE)是一种数据库查询语言,它允许您通过设计模板(对其进行比较)来创建查询,而不是通过使用谓词条件的语言(如SQL)。
上一次我使用了db4o的QBE引擎演示了数据检索,这里将快速回顾一下。
首先看一下这个绝对简单的数据库。
它由一种类型组成,清单1列出了其定义:
清单1.Person类
与POJO类似,Person并不是一个复杂的类。
它由三个字段和一些基本的支持类似POJO行为的方法组成,即toString()和equals()。
(阅读过JoshuaBloch的EffectiveJava的读者将注意到我忽略了hashCode()实现,很明显这违背了Rule8。
作者经常使用的典型说法就是,我将hashCode()留给“读者进行练习”,这通常意味着作者不想解释或认为没有必要提供手头的示例。
我同样将它留给读者作为练习,请自行判断我们这里的练习属于哪种情况。
在清单2中,我创建了6个对象,将它们放入了一个文件中,然后使用QBE调用名字匹配
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 面向 Java 开发人员的 db4o 指南 开发人员