前言

在开源面向对象数据库 db4o 之旅 系列文章的第 1 部分:初识 db4o 中,作者介绍了 db4o 的历史和现状,应用领域,以及和 ORM 等的比较; 在第 2 部分:db4o 查询方式中, 作者介绍了 db4o 的三种不同的查询方式:QBE、SODA 以及 Native Queries,并分别通过这三种不同的途径实现了两个关联对象的查询。

前面我们已经介绍了如何在 db4o 中查询以及添加对象,在本文中我们将会向您介绍在 db4o 中如何对对象进行更新以及删除操作。

更新数据

场景一

我们来设想这样的场景:一位名叫“张三”的人买了车,并上好了牌照(如本系列第二部分之代码),而他基本信息的地址并不详细,只写了“成都市”,在一次主管部门检查此人信息的时候,发现了这个问题,并立即着手修改。

在 db4o 中,我们这样来实现对这个用户信息的修改(清单1):

清单1. 修改地址

package com;import bo.People;import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.query.Predicate;public class DB4OTest{public static void main(String[] args){//打开数据库ObjectContainer db = Db4o.openFile("auto.yap");try{ObjectSet<People> result = db.query(new Predicate<People>() {public boolean match(People people) {return people.getName().equals("张三");}});People people = result.next();//修改地址people.setAddress("成都市金牛区xxx号");db.set(people);}finally{//关闭连接db.close();}}
}

修改数据是如此的简单,通过 NQ 查询出 People 对象,接着修改其地址,最后保存即可。现在我们来看看修改是否成功, 打开 ObjectManager ,如图 1 所示,我们可以看到数据库里的用户数据已经更新了。

图1. 修改地址

与本系列文章第二部分不同的是,我们利用 ObjectSet<People> result 来获取返回结果,而不是 List<People> list。查阅 ObjectSet 的 API 我们发现 ObjectSet 实际上继承了 java.util.List 和 java.util.Iterator。为什么要继承两个接口?这是由于 db4o 为了方便开发者而有意这样设计的,db4o 的设计目标就是轻量级,这样的继承方式为 ObjectSet 提供了多种特性,而无需开发者在多个集合接口之间转换。

场景二

让我们考虑下面这个场景:
由于工作原因,“张三”要离开省会去其他城市发展,他的汽车也要在那里使用,为了方便,他还是决定重新更换为本地牌照。

这次我们几乎和场景一采用同样的代码,但结果却不同(清单2):

清单2. 修改地址和车牌(不成功)

package com;import bo.People;import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.query.Predicate;public class DB4OTest{public static void main(String[] args){//打开数据库ObjectContainer db = Db4o.openFile("auto.yap");try{ObjectSet<People> result = db.query(new Predicate<People>() {public boolean match(People people) {return people.getName().equals("张三");}});People people = result.next();//修改地址people.setAddress("绵阳市xx区xxx号");//修改车牌号people.getAutoInfoList().get(0).setLicensePlate("川B00000");db.set(people);}finally{//关闭连接db.close();}}
}

想必应该保存成功了吧,只是多加入了设置车牌的代码。打开 ObjectManager,如图 2 所示。很奇怪,地址保存成功了,而车牌却根本没变化。

图2. 修改地址和车牌(不成功)

其实这也是 db4o 的有意安排。设想一个复杂对象有很多成员,并且这些成员又有自己的成员。当更新该对象,db4o 将不得不更新其所有的关联对象、关联对象的关联对象,等等。这将引起严重的性能惩罚,而且在大部分的情况下是没有必要这样的。

db4o 引入了“更新深度(update depth)”这一概念来控制被更新的对象成员树深度。默认的更新深度是 1,这就意味着只有基本类型和 String 类型的成员变量可以被更新,而修改对象成员将得不到任何反映,例如本例中修改 People 对象的 _autoInfoList 成员。

为了能更新成员对象,ob4o 提供了 cascadeOnUpdate() 方法,该方法必须在每次开启数据库之前设置清单3:

清单3. 修改地址和车牌(成功)

package com;import bo.People;import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.query.Predicate;public class DB4OTest{public static void main(String[] args){//级联设置Db4o.configure().objectClass("bo.People").cascadeOnUpdate(true);//打开数据库ObjectContainer db = Db4o.openFile("auto.yap");try{ObjectSet<People> result = db.query(new Predicate<People>() {public boolean match(People people) {return people.getName().equals("张三");}});People people = result.next();//修改地址people.setAddress("绵阳市xx区xxx号");//修改车牌号people.getAutoInfoList().get(0).setLicensePlate("川B00000");db.set(people);}finally{//关闭连接db.close();}}
}

这下终于如愿以偿,如图 3 所示。其实 db4o 为开发者想得很周到,关键是如何用好这些特性。

图3. 修改地址和车牌(成功)

删除数据

场景三

“张三”换了工作后,事业发展很快,准备把车卖了换新的,于是他去交管部门办理移交手续,删除关联的车辆信息清单4:

清单4. 删除车辆

package com;import bo.AutoInfo;import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.query.Predicate;public class DB4OTest{public static void main(String[] args){//打开数据库ObjectContainer db = Db4o.openFile("auto.yap");try{ObjectSet<AutoInfo> result = db.query(new Predicate<AutoInfo>() {public boolean match(AutoInfo ai) {//匹配姓名和车牌号return ai.getLicensePlate().equals("川B00000") && ai.getOwnerNo().getName().equals("张三");}});AutoInfo ai = result.next();//删除车辆信息db.delete(ai);}finally{//关闭连接db.close();}}
}

如图 4 所示,所关联的车辆信息已被删除了。

图4. 删除车辆信息

场景四

在场景三的基础上修改一下,设想“张三”由于工作不顺,导致最后维护汽车的开支都困难,他不得不退出有车一族的行列清单5:

清单5. 删除所有信息

package com;import bo.People;import com.db4o.Db4o;
import com.db4o.ObjectContainer;
import com.db4o.ObjectSet;
import com.db4o.query.Predicate;public class DB4OTest{public static void main(String[] args){//级联设置Db4o.configure().objectClass("bo.People").cascadeOnDelete(true);//打开数据库ObjectContainer db = Db4o.openFile("auto.yap");try{ObjectSet<People> result = db.query(new Predicate<People>() {public boolean match(People people) {//匹配姓名return people.getName().equals("张三");}});People people = result.next();//删除车主以及关联的车辆信息db.delete(people);}finally{//关闭连接db.close();}}
}

用过 Hibernate 的开发者都知道,它的级联删除让人留下了深刻印象,第一次使用的时候都会为之振奋。db4o 也为开发者提供了级联删除,和场景二的级联更新一样, cascadeOnDelete() 是专门为删除准备的,基本概念和 cascadeOnUpdate() 一致。打开 ObjectManager 我们会发现数据库已经清空了,张三的购车经历到此结束。

结论

通过本系列文章,db4o 的优势已经体现得淋漓尽致,它的添加、更新、删除是如此的简单,正如 db4o 的口号那样——“仅需一行代码就能存储复杂结构对象,极大的降低了开发时间和成本,提供高效的性能,无需 DBA 干预”。

如本文有不详尽之处,大家可以参考官方的《用户指南》或访问 db4o 官方中文论坛,db4o 中文社区正在火热成长!

参考资料

学习

  • db4o 官方网站 。
  • 面向对象数据库 db4o 之旅系列 :查看此系列文章完整列表。
  • ODMG 官方网站 :了解 ODMG 技术。
  • developerWorks Java 技术专区 :数百篇关于 Java 编程各个方面的文章。

获得产品和技术

  • 下载 db4o 免费版 。

讨论

  • db4o 开发者论坛:讨论 db4o 技术。
  • developerWorks Java 论坛 :学习 Java 技术。

作者简介

 

Rosen Jiang 来自成都,是 db4o 和 OO 的忠实 fans,是 2005 年 db4o 的 dvp 获得者之一。他正在 J2me 应用中使用 db4o,你可以通过 rosener_722@hotmail.com 和他联系。

Chris 来自香港,热爱开源和 db4o。他创办了中国最火热的 Java 和开源社区 Matrix(http://www.Matrix.org.cn), 你可以通过 chris@Matrix.org.cn 和他联系。

张黄瞩,热爱开源软件,熟悉 Java/C/C++ 编程语言,对数据库技术网络技术均感兴趣。你可以通过 zhanghuangzhu@gmail.com 联系他。

IBM DeveloperWorks(IBM DW) 版权所有!引用、转贴本文应注明本文来自 IBM DW。

Rosen 2006-12-30 19:11 发表评论

开源面向对象数据库 db4o 之旅: 深入 db4o “db4o 之旅(三)”相关推荐

  1. 开源面向对象数据库 db4o 之旅: db4o 查询方式“db4o 之旅(二)”

    前言 在 开源面向对象数据库 db4o 之旅 系列文章的第一部分:初识 db4o 中,作者介绍了 db4o 的历史和现状,应用领域,以及和 ORM 等的比较.在这篇文章中,作者将会介绍 db4o 的安 ...

  2. 开源面向对象数据库 db4o 之旅: 初识 db4o“db4o 之旅(一)”

    前言 业界对持久存储领域的追求从未停止过,为了更方便.更容易地用对象表达我们的思维,开源领域和商业领域都涌现了许多新技术, ORM 的出现恰恰说明了这点.最近一年,业界也在反思,到底 ORM 给我们带 ...

  3. db4o面向对象数据库::NoSQL

    完全原生于 Java 和 .NET 100% 面向对象, 抛开对象-关系映射 为嵌入式应用优化 开源,可以基于GPL协议免费使用. db4o 的目标是提供一个功能强大的,适合嵌入的数据库引擎,可以工作 ...

  4. db4o官方停止支持及面向对象数据库的一些感想

    前一段时间试用了db4o,真心觉得不错,但自己在国内搜索了一下,并没有找到任何一个专门的论坛和面向对象的数据库产品,深感这东西在国内并没有太普及.但自己试用觉得这个东东真心不错(当然也有自己的优势和劣 ...

  5. 面向对象数据库NDatabase_初识

    面向对象数据库介绍 先拿ORM来说吧. ORM是什么, 为什么用ORM 一般来说程序是面向对象的(或者主流是面向对象的), 也就是O(Object), 那就会有对象, 关联, 继承, 聚合等 一般来说 ...

  6. 几种开源NOSQL数据库

    几种开源NOSQL数据库 2017年06月30日 23:36:13 lm_y 阅读数 13655更多 分类专栏: java 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载 ...

  7. 三款开源关系型数据库对比:MySQL、PostgreSQL、SQLite

    在这篇DigitalOcean文章中,我们将尝试理解一些最常用.最流行的关系型数据库管理系统(RDBMS)的内核区别.我们将会探索最底层的区别--特性与功能,它们如何工作,在哪方面更出色,以帮助程序员 ...

  8. 开源NoSQL数据库介绍

    目录 一.概述 二.NoSQL数据库 1. MongoDB 2. Cassandra 3. CouchDB 4. Hypertable 5. Redis 6. Riak 7. Neo4j 8. Had ...

  9. 开源分布式数据库中间件

    转自:https://www.csdn.net/article/2015-07-16/2825228 MyCat:开源分布式数据库中间件 为什么需要MyCat? 虽然云计算时代,传统数据库存在着先天性 ...

最新文章

  1. 业务逻辑全写在sql_TiDB 在转转的业务实战
  2. 我就不信看完这篇你还搞不懂信息熵
  3. Internet Explorer 已停止工作 解决办法
  4. 整数划分递归相关问题
  5. WPF 框架全构建环境虚拟机硬盘分享
  6. 浏览器渲染机制面试_【前端面试必考题】页面渲染机制(一)
  7. 目标跟踪-粒子滤波算法
  8. mysql 数据库优化之执行计划(explain)简析
  9. 八戒科技服务技术负责人鸿鹄真人:做好技术负责人的4个关键特质
  10. jquery validate的验证规则和验证提示
  11. tablepc是什么平板电脑_iPad不是平板!想买Tablet PC的看过来
  12. android模拟器上https抓包
  13. M1芯片,PS2022版真的来了。Photoshop 2022 for Mac中文版介绍安装教程,支持Monterey系统
  14. rv1126rv1109开发环境搭建
  15. 第四篇:UE4视角切换节点,Possess和Set View Target With Blend的区别
  16. html中em使用例子,HTML DOM Emphasized用法及代码示例
  17. 阿里系App抓包分析(三)
  18. 留下岁月的痕迹,不负自己所望
  19. 计算机科学概论读后感
  20. 乌龟喂食规律:乌龟多久喂一次?

热门文章

  1. python语言学习记Day1
  2. linux 网络性能工具iperf 使用总结
  3. Linux软件安装rpm、yum
  4. 一些简单的java编程题(1) ————求10000以内的完数
  5. C语言判断是否为素数(质数)
  6. spring+dbcp连接池源码分析
  7. 火车进站问题,堆栈的使用
  8. 网页爬虫中\xa0、\u3000等字符的解释及去除
  9. 博文审核不通过怎么办
  10. 《树莓派项目实战》第十四节 使用L298N驱动板模块驱动直流电机(马达)