在本系列中,我介绍了使用 db4o 进行面向对象数据管理的基本要素。但是还有一点没有讨论,那就是如何在 Web 应用程序中使用 OODBMS,以及与在 Swing 或 SWT 中使用 OODBMS 有何不同。可以说,我忽略的这些内容是 Java(或 .NET)开发人员不能忽略的。
一定程度上,我应该关注 OODBMS 最引人注目的功能:面向对象数据的存储、操作和检索。同样地,OODBMS 供应商也试图实现诸如事务管理和安全性之类的核心功能。这些功能与各种 RDBMS 的相应功能类似,并且具有类似的选项范围。
在面向 Java 开发人员的 db4o 指南 的最后一期中,我将要讨论任何数据存储系统(面向对象的、关系的,等等)都应该拥有的 3 个特性。了解 db4o 如何支持应用程序安全性、分布和事务。
迄今为止,我为本系列编写的代码都假设数据库只有一个客户端。换句话说,只会为数据库创建一个逻辑连接,所有的交互都通过该连接来完成。对于要访问配置数据库或逻辑存储系统的 Swing 或 SWT 应用程序,这是一个非常合理的假设。但是对于 Web 应用程序,即使是所有的存储都是在 Web 表示层完成的程序,这个假设也不太符合实际。
在 db4o 系统中,打开第二个数据库逻辑连接非常简单,即使当数据库驻留在本地磁盘上时也是如此。我只需要首先添加一个调用创建 ObjectServer
,并从 ObjectServer
获取 ObjectContainer
对象。让 ObjectServer
在端口 0 上监听,这样会告诉它以 “嵌入式” 模式运行,并且在进行下一个探察测试时不会打开(或威胁)实际的 TCP/IP 端口。
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
注意,当运行该测试时,我向测试代码中添加了一些输出行。需要对发生的行为进行跟踪,因为 db4o 需要一直保持对打开对象的引用。还应该确保了解内存中对象的更新是在什么时候和什么位置 “传递” 给第二个客户端的。
适用用例:当我进行 set(ted1)
调用时,db4o 系统修改其内部状态,以了解 ted1
是脏对象并需要更新。但是,在使用 ObjectContainer
上的 commit()
方法提交显式事务之前,它不会进行实际更新。此时,数据被写入磁盘,但是跟磁盘上的数据相比,内存中 client2
的对象视图仍然是陈旧的(回顾一下探察测试的输出。在阅读本系列时,您已经 在流览器旁边的控制台窗口运行了该代码)。
改进方法很简单:client2
使用 extension
对象上的 refresh()
方法刷新它在内存中的对象图视图,extension
对象由 ext()
返回。注意激活深度是一个重要因素:当刷新对象时,您希望 db4o 深入到对象图的哪个深度?在本例中,逐步降低深度(single step down)就可以检索修改的 Employee
了,但是对于不同的情形,应该重新考虑。
一旦其对象视图被刷新,client2
就会了解到所做的更改。快速查询将会显示出公司领导的新头衔。
大多数时候,多个客户端不会只具有单个进程,而是可以跨多个进程。例如,在典型的客户机-服务器风格中,将有多个客户机而不是一个 servlet 容器与单个服务器会话。在 db4o 中实现此功能的方法与 清单 1 大体相同。惟一的区别在于需要用一个非 0 的端口号来打开服务器。该端口号表示服务器监听的 TCP/IP 端口。所有基于 TCP/IP 的通信都是这样,当进行连接时,客户端必须指定主机名和端口。
自然地,当涉及一个端口时,就得考虑安全性,因为您不能允许 “所有人” 连接服务器并进行查询。在传统的 RDBMS 实现中,供应商提供了一个强大的安全模型,当数据库连接打开时,要访问数据库实例的部分或所有内容,必须向数据库发送凭证(用户名和密码)。
db4o 实现也是这样,至少在效果上是一样的。但是 db4o 数据库实例创建者设置授权安全策略的方法与常见 RDBMS 场景有很大区别,如清单 2 所示:
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/a41954a27d6ad96fa2c2cf816e677448.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/1327ab569c1ae82736693a50b8e33378.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/37c8bf68cdc3cc81759c34160776bc53.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/7ff8d92cded7e0ce15e7ca1acc870052.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6a9c071a08f1dae2d3e1c512000eef41.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/717446ca04a6125dc5b6b54e0fa14ab4.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/0196c3df5ea9e936f21e9932cca91014.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/6810355c2f78c12e91b7997a8e8c583a.gif)
要在 db4o 中定义访问控制,只需使用 grantAccess()
方法,它授权对整个数据库实例的访问。这种方法简化了安全设置场景,但是这样一来就无法使用最小特权原则了,因此该方法既有优点也有缺点。
![]() |
|
目前 db4o 还不支持更加粒度化级别的解决方式,其他 OODBMS 系统可能更加灵活。您应该确保只使用了最小数量的安全性凭证。如果不能限制登录需要使用的资源,那么至少可以限制系统访问原则的数量。
分布式系统的安全性问题 — 尤其是 Fourth Fallacy of Enterprise Computing(参考 参考资料 中的 Effective Enterprise Java)— 说明,不能认为只有监听网络通信量的人或代码才是可信的。这意味着您必须确保在网络中传输的数据不是明文和二进制形式(如果使用的二进制形式的格式众所周知,那么它和明文形式是相同的)。
关心安全性的开发人员也会关心存储在 db4o 文件中的数据,因为文件 “仅仅是文件”,因此打开文件和阅读其中的内容会将文件暴露给攻击者(关系数据库也存在着这类问题)。
解决方案是对文件进行加密,这在 db4o 中比较简单。对于大多数场景,db4o 的默认加密模式 eXtended Tiny Encryption Algorithm (XTEA) 对暴露给攻击者的数据进行模糊化。对于其他实例,db4o 提供了一个定制加密 “技巧”,支持使用第三方加密提供程序(不要定义自己的加密格式,除非您可以编写出论文挑战既有标准,并受到全世界密码学家和数学家的关注,而且可以在主流安全会议上进行辩护。如果达到了这些要求,您可以 考虑使用它,毕竟,没有被发现并不意味着不存在)。
保护有线形式(wire-format)的数据传输比较困难,因为 db4o 6.3 及以前的版本都没有提供工具跨安全的传输线(比如通过 SecureSocket
传输的 SSL)进行通信。这意味着任何敏感数据都必须以加密的方式传输,这暗示着对象本身应该包含某种形式的加密(如果 db4o 可以直接实现这一功能就太好了;在撰写本文的时候,db4o 6.4 版已经计划支持将 SocketFactory
传递到 openServer
调用,因此您可以使用 SecureSocket
连接取代完全开放的 Socket
连接)。
注意可以使用定制编组程序 通过 “横切(cross-cutting)” 方式进行传递以保护数据。顾名思义,这使您能够控制数据的打包(和解包)方式,以在线路上进行传输。这种方法与通过 Externalizable
接口定制串行化非常相似:编写一个实现 ObjectMarshaller
接口的类,实现 readFields()
和 writeFields()
方法,然后告诉 db4o 系统对特定类的对象使用定制的编组程序,具体方法是在目标类的 ObjectClass
上调用 marshallWith()
。完整的代码如下:
Db4o.configure().objectClass(Item.class).marshallWith(customMarshaller); |
这样做不会保护整个线路 — 攻击者仍然可以查看保存的对象类型 — 但是它会在网络上进行节点到节点传输时阻止数据被别人查看。
当 db4o 选项 “嵌入式和客户机/服务器” 不能满足需要时,比如将数据存储到特定的文件格式或非传统的数据存储资源中,db4o 库允许创建 IoAdaptor
的一个子类,该类是 db4o 在存储对象时写入数据的关键抽象。这让存储具有一定程度的灵活性,而大多数 RDBMS 系统都不具有这种灵活性。
关于 OODBMs 和 db4o,还有大量内容值得讨论和研究,但是我已经完成了预定目标并决定暂时结束本系列。我相信我展示了一个关于 db4o 和面向对象数据管理的良好示例,并从 Java 开发人员的角度介绍了 RDBMS 不同于 OODBMS 的特性。我展示了如何使用 db4o 轻松地跟踪关联(track association);db4o 如何获得作为数据库优秀概念的继承性;db4o 如何使用定义对象的原生编程语言简化对象检索。
我也讨论了 OODBMS 的一些不足,以及 db4o 与 RDBMS 都存在的缺陷,比如在处理客户机-服务器网络中的 “往返传输” 时出现的性能问题。
只要跟随本系列的示例并试用了其中的代码,就会获得使用任何 OODBMS 系统(不只是 db4o)的必备技巧。您可以尝试将所学知识应用到 Cache' 或 Versant 上。大多数 OODBMS 都遵循相同的基本编码约定和惯用表达式,而且实际上 db4o 对原生查询的支持已逐渐成为一种标准,使该特性成为所有 OODBMS 的一部分。
希望您能在本系列中找到所需的内容,并已准备好在您自己的项目中使用 OODBMS。这将是一种轻松的体验,不用担心关系模式和所有相关的内容。因此,请放松心情:试验、实现、在实践中体验乐趣,不要忘了来信告诉我您的经验(或者给我发送电子邮件)。
学习
- 您可以参阅本文在 developerWorks 全球站点上的 英文原文 。
- 面向 Java 开发人员的 db4o 指南 (Ted Neward,developerWorks):该系列介绍了 db4o,db4o 是一个利用当今面向对象语言、系统和理念的开源数据库。
- 追求代码质量 (Andrew Glover,developerWorks):了解更多有关开发人员测试技术的信息,比如探察测试。
- The Eight Fallacies of Distributed Computing:由 Peter Deutsch 在 1994 年提出。Arnon Rotem-Gal-Oz 从更新的角度介绍了这些信息。
- Effective Enterprise Java (Ted Neward,Addison-Wesley Professional,2004 年 8 月):通过两个特定于 Java 企业开发的例子对 “8 种谬论” 进行了更新。
- “When to Use an ODBMS”(Rick Grehan,ODBMS.org):其中列出了可以使用 OODBMS(比如 db4o)的应用场景。
- The Database Column:这是一个拥有多个作者的 blog,致力于数据库技术的研究和创新。
- db4o 主页:开始使用 db4o。
- ODBMS.org:了解关于面向对象数据管理系统的更多信息。
- developerWorks Java 技术专区:其中有数百篇关于 Java 编程各方面的文章。
- IBM Information Management 新手入门:还是对 OODBMS 不大信服吗?从这里可以获得有关 IBM 关系数据库管理系统(RDBMS)服务器系列的更多信息。