继往开来 吐故纳新
日历
网志分类
· 所有网志 (990)
· 个人作品 (62)
· 软件设计 (33)
· 面向对象编程 (22)
· JavaAPI (39)
· Java开源工具 (31)
· Swing (34)
· Java语法细节 (39)
· 样式表CSS (12)
· XML (10)
· J2EE(JavaEE) (23)
· 算法数据结构 (64)
· 正则表达式 (4)
· 软件知识 (6)
· Java线程 (9)
· Web开发.Jsp/Servlet/Struts (20)
· 程序随想录 (7)
· Spring (5)
· Hibernate (7)
· J2SE 高级 (2)
· J2SE 高级 (0)
· Web开发.Ajax (16)
· Web开发.JavaScript (43)
· DB4O (2)
· Web开发.CSS/Html (22)
· C# (20)
· ERP (4)
· JDBC (1)
· 编程资源 (16)
· 编程感悟 (29)
· DB/Sql (13)
· VB (29)
· VC (2)
· 桌面脚本 (3)
· 新兴软件 (3)
· 英语学习 (21)
· 网文转载 (159)
· 职场风云 (39)
· 诗词歌赋 (32)
· 生活感言 (77)
· 奇文共赏 (13)
· 财经纵横 (6)
· 未分类 (11)
站内搜索
友情链接
· 歪酷博客
· 我的歪酷 非非共享界
· 偶要雷锋
· 豆瓣
· nczonline
· 当当网
· easyjf中文站
· Donews
· 天极Java文章列表
· W3CSchool
· taiten的BLOG
· Dojo中国
· Dojo
· Extjs.com
· Lifehack中文网志
· JaveEye的一个AS专题
· Banq's JDon
· Java 中文网址大全
· 梦想Java
· 360Doc个人图书馆
· java开源大全
· 我在硅谷动力的软件下载站
· 站长中国
· 随意贴
· CSS教学素材站
· java 参考中文站
· 面向构件与SOA社区
· 彩字生成
· 派派小说论坛
· 如坐春风
· 英语学习网
· BBC CHina
· www.dlbang.com
· 古文竖排格式在线转化工具
· 免费家谱
· 图片上传基地
· 风景壁纸
· 和风细雨
· MyC#BlogInCsdn

订阅 RSS

0207440

歪酷博客

开此博一为经验积累,二为资料收集,三为同道交流,四为资源共享.
« 上一篇: 【整理】使用JS收起和弹出树菜单 下一篇: 【原创】用于消除向View层传递ActionForm名硬编码的函数 »
Junglesong @ 2006-09-01 14:34

Db4O数据库之运用(原创)

文/junglesong

注:欢迎与我讨论(junglesong@gmail.com)

Db4O全名DataBase For Object,是一个对象数据产品,它的数据输入输出全是对象,完全消除了以前面向对象的系统和关系型数据库之间阻抗不匹配的问题,也省却了OR Mapping工具的烦琐配置,是我们更能把注意力集中到项目上.关于Db4O的细节可以参考这个网址:http://developer.db4o.com/blogs/chinese/,或者直接去其大本营http://www.db4o.com/.

一.如何在项目中使用Db4O.
这非常简单,到Db4O大本营http://www.db4o.com/下载最新的开发包并加入自己的Lib即可,我选择的是db4o-5.2-java1.2.jar.
以下将对我在项目中使用Db4O的过程进行一下讲述.

二.构建DataBaseForObject基本类.
构建DataBaseForObject基本类的基本目的是为调用DB4O的个个Service类提供统一的借口,它是Adapter模式的一种体现.
此外,为加快查询速度,我还加入了Jakerta的对象池支持.
public class Db4OFactory implements PoolableObjectFactory {
  private static String DataFilePath = "";

  public static final String DataFileName = "DBFile.dat";
 
    public Object makeObject() throws Exception {
        Object obj = Db4o.openFile(DataFilePath);
        //System.err.println("Making Object " + obj);
        return obj;
    }

    public void activateObject(Object obj) throws Exception {
        //System.err.println("Activating Object " + obj);
    }

    public void passivateObject(Object obj) throws Exception {
        //System.err.println("Passivating Object " + obj);
    }

    public boolean validateObject(Object obj) {
        return true;
    }

    public void destroyObject(Object obj) throws Exception {
      ObjectContainer db=(ObjectContainer)obj;
      db.close();
        //System.err.print ln("Destroying Object " + obj);
    }
   

  public static void setDataFilePath(String dataFilePath) {
    DataFilePath = dataFilePath;
  }

  public static String getDataFilePath() {
    return DataFilePath;
  }
}

下面是其主要方法:
public class DataBaseForObject {
       // 删除一个对象
  public static synchronized void remove(Db4OStorable obj) {
    PoolableObjectFactory factory = new Db4OFactory();
    ObjectPool pool = new StackObjectPool(factory);
    ObjectContainer db = null;

    try {
      db = (ObjectContainer) pool.borrowObject();

      Query query = db.query();
      query.descend("id").constrain(obj.getId());

      ObjectSet objSet = query.execute();
      if (objSet.hasNext()) {
        db.delete(objSet.next());
      }
     
      db.commit();
      db = null;

    } catch (Exception e) {
      System.out.println("从Db4Obj数据库删除对象错误!");
      e.printStackTrace();
    } finally {
      try {
        if (db != null) {// 避免将一个对象归还两次
          pool.returnObject(db);
        }
        pool.close();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

        // 存储或更新一个对象
  public static void save(Class objClass, Db4OStorable obj) {
    PoolableObjectFactory factory = new Db4OFactory();
    ObjectPool pool = new StackObjectPool(factory);
    ObjectContainer db = null;

    try {
      db = (ObjectContainer) pool.borrowObject();

      Query query = db.query();
      query.constrain(objClass);
      query.descend("id").constrain(obj.getId());

      ObjectSet objSet = query.execute();

      if (objSet.hasNext()) {
        Db4OStorable found = (Db4OStorable) objSet.next();
        found.update(obj);
        db.set(found);
      } else {
        db.set(obj);
      }
      db.commit();
      db = null;

    } catch (Exception e) {
      System.out.println("从Db4Obj数据库更新对象错误!");
      e.printStackTrace();
    } finally {
      try {
        if (db != null) {// 避免将一个对象归还两次
          pool.returnObject(db);
        }
        pool.close();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }
  }

        // 进行对象查询
        public static ArrayList searchBy(Predicate predicate) {
    PoolableObjectFactory factory= new Db4OFactory();
    ObjectPool pool = new StackObjectPool(factory);  
    ObjectContainer db = null;

    ArrayList retval = new ArrayList();

    try {
      db=(ObjectContainer)pool.borrowObject();
     
      ObjectSet objSet= db.query(predicate);

      while (objSet.hasNext()) {
        Object obj = objSet.next();
        retval.add(obj);
      }
     
      db=null;
    } catch (Exception e) {
      System.out.println("从Db4Obj数据库查询对象错误!");
      e.printStackTrace();
    } finally {
      try {
        if (db != null) {// 避免将一个对象归还两次
          pool.returnObject(db);
        }
        pool.close();
      } catch (Exception e) {
        e.printStackTrace();
      }
    }

    return retval;
  }

}

使用这三个函数就可以对各种对象进行CRUD操作了.

为了区别同类型的不同对象,它们需要唯一的标志Id,所以我让每种需要进行持久化的类都实现了Db4OStorable接口,代码如下:
public interface Db4OStorable{
  public String getId() ;
  public void setId(String id) ; 
  public void update(Object obj);
}

这样一来,各个类就有了统一的接口,代码就可以进行统一实现了,避免为一个类加一种判断.

二.构建各Service类.
   为了实现对各种类型的不同处理,我们需要为每种对象提供一个Service类,让它来充当DB4O数据与对象之间的桥梁作用,这些类可以根据进行各种复杂的处理而不影响DataBaseForObject 的纯洁性.

下面是一个Service类的示例:

public class ProjectService{
  public static boolean save(Project project) {
    DataBaseForObject.save(Project.class,project);   
    return true;
  }
 
  public static boolean delete(Project project){
    project.getFile().delete();
    DataBaseForObject.remove(project);   
    return true;
  }

        public static Project getObjById(String id) {
   
    final String Id=id;
    Predicate predicate = new Predicate() {
      public boolean match(Project prj) {
        boolean retval = prj.getId().equals(Id);
        return retval;
      }
    }; 
   
    ArrayList list=DataBaseForObject.searchBy(predicate);
   
    if(list.size()==0){
      return null;
    }
   
    Project prj=(Project)list.get(0);
    return prj;
  }

        public static ArrayList getAllDatum(Predicate predicate,SortBean sortBean){
    ArrayList list=DataBaseForObject.searchBy(predicate);
    Collections.sort(list,new ProjectComarator(sortBean));
    return list;
  }
}

可以看出,上述四个方法对于Project对象的CRUD操作更加方便了.

三.对象的具体操作.
1)Create创建操作
Project project=new Project();
project.setId(Util.getIdbyTime());// 注意这里是根据时间取出唯一ID,还可以有别的规则
project.setXXX(xxx);
.......
ProjectService.save(project);

2)Delete删除操作
ProjectService.delete(project);

3)Update更新操作
project.setXXX(xxx);
.......
ProjectService.save(project);
这里要多说几句,更新操作首先要ID一致,这里就不能改编ID值,否则就变成了创建;其次更新操作依赖于对象对Db4OStorable的update方法的实现,彻底更新一个对象需要用新对象的所有成员替代旧对象的所有成员,下面是我的一个实现例子:
        public void update(Object obj){
    Project another=(Project)obj;
   
    this.id=another.id;
    this.pid=another.pid;
    this.path=another.path;
    this.title=another.title;
    this.type=another.type;
    this.status=another.status;
    this.concept=another.concept;
    this.creator=another.creator;
    this.chief=another.chief;
    this.members=another.members;  
    this.file=another.file;  
  }
这个方法没实现完全的话,对象不能完全更新,切记.

4)Search查询操作.
DB4O提供了多种查询方式,经过一段时间后我决定采用精确灵活的predicate查询方式,
请看其使用:
               Predicate myprojectsPredicate = new Predicate() {
      public boolean match(Project prj) {
        boolean retval = true;

        retval = retval
            && (prj.getType().equals(Consts.ProjectType_Project));
        retval = retval && (prj.getPid().equals("0"));
        retval = retval
            && (prj.getChief().equals(Username) || Util.strContain(
                prj.getMembers(), Username));

        return retval;
      }
    };
    ArrayList projectResult = (ArrayList) ProjectService.getAllDatum(myprojectsPredicate, new SortBean("title","asc"));

很明显,由于查询方式是Java语言,它更自然,易懂和容易修改,而且不会把业务耦合到SQL中,相对冗长复杂的SQL要强很多,比HibernateHQL也简单不少.
不过美中不足的是数据的排序,我们需要一个实现了Comparator接口的类来实现排序,下面是我的实现过程,如果你对Comparator比较熟悉的话可以掠过.
你也可以不写得这样负复杂.

public class SortBean{
  private String field;
  private String order;
 
  public SortBean(String field,String order){
    this.field=field;
    this.order=order;
  }
 
  public String getField() {
    return field;
  }
  public void setField(String field) {
    this.field = field;
  }
  public String getOrder() {
    return order;
  }
  public void setOrder(String order) {
    this.order = order;
  }
}

public final class ProjectComarator implements Comparator{
  private SortBean sortBean; 

  public ProjectComarator(SortBean sortBean){
    this.sortBean=sortBean;
  }
 
  public int compare(Object arg0, Object arg1) {
    Project op1=(Project)arg0;
    Project op2=(Project)arg1;
   
    if(sortBean==null){
      return op2.getId().compareTo(op1.getId());
    }
   
    if(sortBean.getField().equals("title") && sortBean.getOrder().equals("asc")){
      return op1.getTitle().compareTo(op2.getTitle());
    }
    else if(sortBean.getField().equals("title") && sortBean.getOrder().equals("desc")){
      return op2.getTitle().compareTo(op1.getTitle());
    }
    else if(sortBean.getField().equals("type") && sortBean.getOrder().equals("asc")){
      return op1.getType().compareTo(op2.getType());
    }
    else if(sortBean.getField().equals("type") && sortBean.getOrder().equals("desc")){
      return op2.getType().compareTo(op1.getType());
    }
    else if(sortBean.getField().equals("status") && sortBean.getOrder().equals("asc")){
      return op1.getStatus().compareTo(op2.getStatus());
    }
    else if(sortBean.getField().equals("status") && sortBean.getOrder().equals("desc")){
      return op2.getStatus().compareTo(op1.getStatus());
    }
    else if(sortBean.getField().equals("concept") && sortBean.getOrder().equals("asc")){
      return op1.getConcept().compareTo(op2.getConcept());
    }
    else if(sortBean.getField().equals("concept") && sortBean.getOrder().equals("desc")){
      return op2.getConcept().compareTo(op1.getConcept());
    }
    else if(sortBean.getField().equals("creator") && sortBean.getOrder().equals("asc")){
      return op1.getCreator().compareTo(op2.getCreator());
    }
    else if(sortBean.getField().equals("creator") && sortBean.getOrder().equals("desc")){
      return op2.getCreator().compareTo(op1.getCreator());
    }
    else if(sortBean.getField().equals("chief") && sortBean.getOrder().equals("asc")){
      return op1.getChief().compareTo(op2.getChief());
    }
    else if(sortBean.getField().equals("chief") && sortBean.getOrder().equals("desc")){
      return op2.getChief().compareTo(op1.getChief());
    }
    else if(sortBean.getField().equals("members") && sortBean.getOrder().equals("asc")){
      return op1.getMembers().compareTo(op2.getMembers());
    }
    else if(sortBean.getField().equals("members") && sortBean.getOrder().equals("desc")){
      return op2.getMembers().compareTo(op1.getMembers());
    }
    else if(sortBean.getField().equals("id") && sortBean.getOrder().equals("asc")){
      return op1.getId().compareTo(op2.getId());
    }
    else if(sortBean.getField().equals("id") && sortBean.getOrder().equals("desc")){
      return op2.getId().compareTo(op1.getId());
    }
    else{
      return op2.getId().compareTo(op1.getId());
    }
    }

  public SortBean getSortBean() {
    return sortBean;
  }

  public void setSortBean(SortBean sortBean) {
    this.sortBean = sortBean;
  }
}

从以上查询代码可以看出,我们的业务全都在Java语言中实现,不需要Sql语句.这对系统的可移植性可修改性都有很好的帮助.


上面就是我在当前项目中使用DB4O对象数据库的全部过程,请大家多批评指教.

2006/09/01

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 





评论 / 个人网页 / 扔小纸条
* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 


 

分类小组论坛
杂谈 , 娱乐、八卦 , 文学、艺术 , 体育 , 旅游、同城 , 象牙塔 , 情感 , 时尚、生活 , 星座 , 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定