龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > JAVA开发 >

Java数据对象(JDO)的前世今生(5)

时间:2009-12-23 15:42来源:未知 作者:admin 点击:
分享到:
另外,我们知道,面向对象概念中,一个属性可以是另一个对象,也就是说,对象之间是存在着引用关系的,这种关系还分为一对一、一对多、多对多等几

  另外,我们知道,面向对象概念中,一个属性可以是另一个对象,也就是说,对象之间是存在着引用关系的,这种关系还分为一对一、一对多、多对多等几种情况。从一个既定对象出发,其某个属性可以是另一个对象,也可以是包含另一组对象的集合。那么,在我们的数据包装里面,当然最好也能方便地处理对象之间的关系。假定现在我们又有一个数据类Group:


  public class Group {
  public int grouId;
  public String groupName;
  public Set users; //set of User
  }


  这里为了简单表明含义,暂不采用getter/setter。

  而User对所属的Group有一个引用:


  public Group belongTo;


  在这里,User.belongTo和Group.users就是一个一对多的关系。

  在我们的数据类中,如何才能实现数据库的存取呢?就算是不考虑Group.users这个反向关系,光是User.belongTo就是一件头疼的事。如果我们在取出一个User对象时同时将其Group对象也取出来,可以保证不会在访问某个用户的组时得到一个null。不过这样有几个缺点:

  1. 数据类的存取处理(JDBC)变得复杂,需要执行很多SQL读取才行,有时候只需要访问User的基本属性时浪费时间和资源;尤其是对集合型属性的预读取,更加可怕

  2. 如果按这个逻辑,双向的关系处理变得危险,很容易陷入死循环,如果要避免,必须在类代码中加入一些特别的机制,也是很麻烦的事

  3. 如果对象之间的关系是更复杂的情况下,比如三个、四个对象之间互相关联,那就是一场噩梦,对代码的编写和维护都异常艰难

  于是,很多开发人员自然而然地退后一步,在User类中只保留一个groupId,并不保存Group对象,这样,可以将User.belongTo属性变成int类型,而另外写一个getter方法:


  public Group getBelongTo() {
  return Group.findById(belongTo);
  }


  而在Group类中,干脆将users属性去掉,只保留一个方法:


  public Set getUsers() {
  return new HashSet(User.findBy("select … from USER where BELONG_TO=?",new Object[]{ new Integer(groupId) }));
  }


  也许细心一点的读者已经看出来了,这里的几个方法都没有将SQLException捕捉,也没有在方法中声明,也就是说是有语法错误的,因为SQLException不是一个RuntimeException。不错,确实是这样,不过我们这里为了简单明了起见,省掉这些处理,以更直接清楚地表达意思。

  这样,实际上,我们的对象关系包装已经名存实亡,在类的内部有很多用于访问所引用对象的复杂代码,这些已经违背了我们将对象关系保持的初衷。有些开发人员甚至不在类中保留访问关系对象的方法,而是在客户调用时再去访问另一对象类的读取方法,如:


  …

  User user = User.getById(…);
  //对user对象进行一些访问,如显示其姓名等等
  Group group = Group.findById(user.belongTo);
  //对group对象进行一些访问,如显示组名等等
  …


  在这样的代码里,实际上我们已经从根本上退回了关系数据库的出发点,这与直接访问数据表有多大区别呢?只不过是在表上面套了一层貌似面向对象的皮而已。不幸的是,这种方式还存在于很多应用之中。

  从前面提到的这些面向对象包装的细节问题,我们可以看到这种传统包装方式的一些主要的缺陷:

  3.1.1.1 数据库命名与对象设计命名的一致性问题

  很多时候,我们兴致勃勃地设计好一个类图,并且经过评审之后,开始对它进行数据库包装,这时候,发现有些属性名在具体的数据库中与该数据库的关键字冲突,不能用作表名或字段名,必须在数据表设计时采用另外的名称,或者很麻烦地加上引号来使用。于是,写数据库处理代码的人有意见了,他必须很清楚地记得一个属性在类中是什么属性名,在表中又是什么字段名,在编写的类逐渐增多后,尤其是一个类经过历次变动之后,或者经过很长时间又需要改动,并去处理这些JDBC代码时,代码维护人员简单要发疯了!

精彩图集

赞助商链接