`
rosen
  • 浏览: 36718 次
  • 性别: Icon_minigender_1
  • 来自: 成都
文章分类
社区版块
存档分类
最新评论

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

阅读更多

前言

在开源面向对象数据库 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. 修改地址

db4o31.jpg

与本系列文章第二部分不同的是,我们利用 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. 修改地址和车牌(不成功)

db4o32.jpg

其实这也是 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. 修改地址和车牌(成功)

db4o33.jpg

删除数据

场景三

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

db4o34.jpg

场景四

在场景三的基础上修改一下,设想“张三”由于工作不顺,导致最后维护汽车的开支都困难,他不得不退出有车一族的行列清单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 中文社区正在火热成长!
 

参考资料

学习


获得产品和技术


讨论

作者简介

 

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 之旅

    2.介绍了面向对象数据库 db4o 的安装、启动以及三种查询语言,并对三种查询语言做了比较。 3.介绍面向对象数据库 db4o 的修改和删除,并对其中出现的问题进行细致分析,引入了“更新深度(update depth)”这一重要...

    android开源数据库框架db4o

    android开源数据库db4o学习demo,里面包含操作数据库常见的四种操作CRUD

    db4o中文指南

    db4o 是一个开源的纯面向对象数据库引擎,对于 Java 与 .NET 开发者来说都是一个简单易用的对象持久化工具,使用简单。同时,db4o 已经被第三方验证为具有优秀性能的面向对象数据库, 下面的基准测试图对 db4o 和...

    db4o 复制系统(dRS)文档

    户在领先的开源对象数据库db4o 的 分 布 式实例和类似 Oracle、MySQL 这样的所有普通关系型数据库之间构建双向对 象同步应用程序。当处理现有 IT 环境中关系型数据库技术的数 据一致性时,dRS 使 db4o 的原生对象...

    android db4o 8.1

    db4o是一个开源对象数据库,它具有以下特点: 1.完全原生于Java和.NET, 2.100% 面向对象, 抛开对象-关系映射, 3.为嵌入式应用优化, 4.开源,可以基于GPL协议免费使用, 5.可嵌入db4o的原始Java和.NET对象数据库...

    DB4O完整教程

    db4o是一个开源的纯面向对象数据库引擎,对于Java与.NET开发者来说都是一个简单易用的对象持久化工具,使用简单

    db4o:db4o(对象数据库)

    这是 db4o(对象数据库)的克隆。 来源来自 它由 Versant 开发、商业许可和支持。 db4o 是用 Java 和 .NET 编写的,并提供各自的 API。 db4o 可以在任何支持 Java 或 .NET 的操作系统上运行。 db4o 在多个许可证...

    java版ss源码-db4o-gpl:db4oGPL版本for.netstardard2.0&Java7+AndroidXamarin...,

    java版s源码db4o的基本原理 db4o 是一种非侵入式持久化系统,它用一行代码存储任何复杂的对象。 在存储对象时,您的应用程序类的类模式会实时分析和调整。 面向对象的查询功能通过本机查询 (NQ)、使用 .NET 语法和...

    db4o-sp:db4o 的空间扩展。-开源

    硕士项目:对象数据库空间扩展。 基于 SQL/MM Spatial 的 API。 完整的技术报告可在下载部分获得。

    db4o对象型数据库学习笔记

    db4o(database for object ) 是一个开源的,面向对象的数据库.  现在有很多的在传统数据库上建立持久关系和ORM影射的工具.  对于ORM,有很多中说法:  业界对持久存储领域的追求从未停止过,为了更方便、更...

    db4o-64-net

    完全原生于Java和.NET 100% 面向对象, 抛开对象-关系映射 为嵌入式应用优化 开源,可以基于GPL协议免费使用.

    db4o boo object browser-开源

    db4oboobrowser是用于db4o(http://www.db4o.com/)数据库文件的简单的基于boo的对象浏览器,它允许您通过GUI或以boo编程语言(http:/ /boo.codehaus.org/)

    db4o-6.1-java.zip

    最新版的开源的对象型数据库工具

    直接保存对象到数据库Demo

    使用开源项目db4o实现在Android中直接保存对象到数据库的Demo

    db4oMembership Provider for ASP.NET 2.0-开源

    db4oMembership Provider 是 db4o (http://www.db4o.com) 开源对象数据库的提供者,实现了框架 .Net 2.0 的新类安全、登录和访问规则,继承了 MembershipProvider 类

    db4o XTEA-开源

    XTEA(扩展的微型加密算法)对db4o开源对象数据库的支持。 XTEA是一种块密码,它使用128位密钥在64位块大小上运行。 极小但非常快速的加密算法(周期少于32轮)

    db4o (database for objects)-开源

    db4o是用于Java和.NET的世界领先的开源对象数据库。 利用快速的本机对象持久性,ACID事务,示例查询,SODA对象查询API,自动的类架构演变,小巧的形式(http://developer.db4o.com)

    ScyDev DB4O Viewer-开源

    DB4Os ObjectManager或OME(对象管理器企业版)的免费替代品。 允许您查看和编辑存储在DB4O数据库中的所有对象。 旧的ObjectManager 6.4不能再用于新数据库,并且新OME具有严重的错误。

    DBite for SQLite(DB4S)项目的官方主页。 以前称为“ SQLite数据库浏览器”和“ SQLite数据库浏览器”。 网站位于:-C/C++开发

    SQLite的DB浏览器什么是SQLite的DB浏览器(DB4S)是一种高质量,可视化的开源工具,用于创建,设计和编辑与SQLite兼容的数据库文件。 DB4S适用于用户和开发人员适用于SQLite的DB浏览器适用于SQLite的DB浏览器(DB4S...

Global site tag (gtag.js) - Google Analytics