Java数据对象(JDO)的前世今生(6)
3.1.1.2 对象的查询仍局限于SQL
这一点也是这种简单的包装方法最不能摆脱关系数据库的地方。上面也已经说过,一些命名冲突带来了很多维护工作量,代码中必须还保留数据表的命名体系,而不是对象类的命名体系。这将使调用人员仍需要清楚记得两套命名体系,无论时间经过多久,或者开发人员是否有流动。
此外,对于普遍需要用到的连表查询,也给应用开发带来困难,这些地方仍不能突破SQL的限制。
3.1.1.3 SQL资源占用多
在处理对象集合访问或者处理集合类型属性时,往往我们只能在同一个Connection中处理一切事务,这就要求一次性地将集合中的对象全部读入,如果集合很大的话,容易造成数据库拥塞,使得性能大打折扣,适得其反。这方面的优化也是很多开发人员一直在努力改进的。
3.1.1.4 对象关系处理复杂
前面提过,对象之间的关系处理上,普通的包装技术是一种表面上的处理,在访问时调用者仍需要用大量的代码进行处理,并且,这还只是读取,在写入关系属性时会有更多的细节问题需要处理。
3.1.1.5 面向对象特色只能应用一小部分
面向对象的包装到前面所说的为止,都还只是很基本的处理,而面向对象的精华:继承和多态,在这里得不到任何帮助。我们放弃了很多合理的设计来迁就数据库的包装。
以上就是基本数据包装的主要缺陷,还有更多的小问题也需要额外的处理。
不过,有责任心的开发人员当然不会就此善罢甘休,他们冥思苦想,可能会用更好的方式来实现对象之间关系的处理,而且还会加入一些延迟访问的机制,将对象之间的引用在需要用的时候才去连接数据库取数据,另外,在类的继承上,他们也试图去在数据库包装上得到体现。
值得感谢的是,一些富有经验的团队在经历若干改进之后,毫不吝惜将他们的成果贡献出来,并将其独立化,成为可复用的组件。这也就是后来出现的对象包装产品,包括商用的和免费的。
3.1.2 产品化包装中间件
面向对象的包装产品化后,逐步推广开来,称作关系/对象映射:O/R Mapping。并且,在产品化的过程中,产品提供者在产品中逐渐提供了更多的功能。先是一些自动命名转换器得以应用,将客户代码中的类名、属性名在内部处理的时候自动地转换到对应的数据库结构命名空间上,这样,应用开发的时候不再关心具体的数据库结构,不再需要记忆不同地命名体系,只需要一心一意地根据类图来进行开发。在此之后,这些O/R Mapping产品的开发团队又向前迈了一大步:引入了词法分析器,提供面向对象的查询语言!很多对象关系的查询使应用开发变得非常方便,使O/R Mapping产品上了一个新的台阶。
3.1.2.1 TopLink
TopLink是一个非常早期的产品,最初面向C++,后来也实现了Java的映射。TopLink性能优异,功能强大,并且提供了独特的查询过滤器机制,以及对关系的处理和查询都非常有效,于是,TopLink逐渐从商用化O/R Mapping产品中胜出,成为市场上的最出色的映射产品。也正因为这一点,最大的关系数据库厂商Oracle将其收购,成为提供最强数据库和最强对象映射中间件的厂商。
3.1.2.2 Castor、Hibernate
TopLink虽然强大,但太强大的东西免不了得意忘形,TopLink开始将用户锁死到自己的产品上,查询方式是最突出的。它的查询体系含有很多别扭的概念(在我看来是如此),但为达到一般O/R产品不能达到的功能,开发者只能接受这些。慢慢地,也产生积怨,再加上其高昂的价格,让很多新老用户望而却步。于是,免费的产品开始崛起。
免费的O/R Mapping工具有很多种,这里只提其中最有影响力的两种:Castor和Hibernate。
Castor是Exolab组织开发的面向Java的包装工具,它最大的特色就是实现了大部分的ODMG OQL规范,在查询上,可以象完全使用一个对象数据库一样类图进行查询(后面会有介绍)。它的原理是通过Java反射API去实现属性的设置和读取。不过由于各种原因,Castor后来的版本更新越来越慢,最终停步在1.0之前,成为至今未出到1.0正式版的O/R Mapping产品。不管怎么样,它还是一个相当不错的产品。
Hibernate是一个现在很火热的O/R Mapping产品,目前已经出到2.0版,它功能一样强大,同样使用Java反射API进行对象的设置,但它的查询语言就是一套比较独特的体系,这一点有点类似TopLink,但Hibernate更具有亲和力,对关系的查询更方便,只不过比起Castor来,在方便性和规范性上还是稍逊一筹。就目前状况而言,Hibernate的用户量和技术支持要强一些。
3.2 面向对象的数据库查询
在对数据库进行面向对象研究的过程中,软件世界的开发人员和设计人员们发现:对数据库能够进行对象化的查询,才是对数据库进行彻底的面向对象化。这体现在我们使用一种全新的数据库查询语言,能够很简洁易懂地对数据库中的对象进行查询。一个典型的例子如下:
假设我们已经有前面提到的两个数据类:User和Group,它们之间有一对多的关系:User.belongTo和Group.users。在数据库中已经存在很多这两个类的实例,以及相互之间的关系。我们可以使用下面的对象式查询语言来查询符合条件的User对象:
select * from User where User.belongTo.name='GROUP1'
或者
select userId,name from User where User.belongTo.name='GROUP2'
等等。从中我们可以看出,通过使用面向对象中的成员属性指定符".",可以让我们达到SQL中的连表的效果,实际上,第一个句查询的SQL等价版本是:
select a.* from USER a, GROUP b
where a.BELONG_TO = b.GROUP_ID
and b.NAME = 'GROUP1'
由此可见,对象式的查询语言,比起实现同样功能的SQL语言来说,简单了很多,意义也更明确,更符合使用者的思维习惯。在类图比较复杂、查询涉及的类又比较多的时候,这种新型的查询语言体现出绝对的优势。
- 上一篇:Java堆的管理--垃圾回收
- 下一篇:Java语言接口与继承的本质