基于Bold的UML模型驱动的数据库应用开发一
Object RDBMS Mapping原理简介
介绍
从Borland推出Delphi1开始,其主要卖点之一就是作为一个RAD开发工具,它可以使用数据感知组件TDataSet,TDataSource,TDbGrid等来非常快速的开发数据库应用。通常来说,只要在界面上摆放一些数据感知组件,设定同数据源的连接,以及对应的表和字段,一个简单的程序就搞定了。RAD的数据库开发方式非常适合于简单的数据库应用程序开发,比如桌面型数据库应用,以及Client/Server应用的原型开发。但是对于复杂的应用程序来说,使用RAD方式开发会产生很多的问题。
首先,使用RAD和数据感知组件,就意味数据表现层同数据库表的紧偶合,每使用一个数据感知组件,都相当于将数据的显示视图偶合到了数据库的某个表或者某个字段上,这样构建的系统的扩展和维护的能力都非常不好。
任何对数据模型的改变都会导致对所有绑定到改动的表或字段的数据感知组件的修改,而从数据集中读取数据,通常是使用FieldByName方法,该方法是以字符串来获得数据集中的字段值,这时编译器是无法帮助我们发现这种组件的绑定是否全部被修正了,即便FieldByName的字段名称错误了,编译器仍然会认为代码没有错误,这样需要改变的组件同库表之间的绑定很难被全部发现,经常会有所遗漏,而由改动引起的错误通常只能是在运行时才能被发现,这就意味着要花更多的时间才能发现错误。而且如果测试时,错误的代码没有被测试所覆盖的话,则错误可能要到客户使用时才会被发现,这时造成的后果可能已经无法挽回了。
而使用面向对象的数据库开发框架的话,对业务域对象的操作都是通过对象的属性或者方法来进行的,如AObj.XXX方法,对对象属性名称或者方法进行了改变的话,编译器会帮助我们找到所有对该对象的不正确的操作,这意味着可以更早地发现和解决bug。
其次,使用RAD和数据感知组件常常意味着更多的网络信息的round trip。在程序中放上一些基于BDE的数据库感知组件,然后同Interbase或者sql server等数据库中的表进行连接,然后启动\bin\sqlmon.exe检测一下网络上的数据流量,就会发现滚动TDBGrid的时候,会产生很多的查询,去获取数据。更多的网络流量,意味着系统的负载的增加,意味着无法支持更多的用户同时对系统进行访问。Delphi后来提出的基于TClientDataSet的DataSnap的三层架构从一定程度上解决了网络round trip过多的问题。但是DataSnap带来的负作用是更加复杂、难于理解和使用。
同时,使用数据感知组件,意味着同数据库的特有特性的紧偶合,比如为了减少代码量和提高效率,经常需要使用一些数据库平台相关的特殊sql,或者将一些复杂的sql写成平台相关的存储过程。
还有就是RAD的开发方式也意味着同特定的数据存取API的绑定,如果从基于BDE的开发方式切换到ADO或者Direct Oracle Access(DOA)的方式,都会导致巨大的改动工作量。
面向对象的数据库开发框架
近年来,越来越多的人认识到使用面向对象的数据库开发框架来进行大型数据库应用的开发有着很多的好处。在项目设计阶段,使用UML建模语言设计业务域对象模型,从模型出发,定义业务域对象,然后使用标准的美观的组件对业务域对象进行操作,设计某些方法将业务域对象保存到数据库,或者从数据库加载,这就是通常所说的OR Mapping,对象-关系映射问题。
同RAD开发方式相比,面向对象的开发方式比较适合信息模型比较复杂的大型系统,同时面向对象的数据库开发框架可以很容易的实现Lazy load的延迟加载技术,因此会产生更少的网络信息round trip,提供较好的性能。另外,框架一般都提供数据库平台无关性的支持,适合于对移植性有较高要求的开发。此外,可以将GUI同数据库解偶合,更容易扩展和维护。不过缺点是对程序员的素质要求的更高。
一般的面向对象数据库开发框架的要求:
对象持续性:框架必须能够以对象的方式存取数据,能存取复杂对象,如复合对象,支持对象之间的关联,比如继承,聚合,关联。
支持对象查询:框架应该提供一种方式可以根据条件查询复合对象以及对象集合。支持标准的对象查询语言,如Object Constraint Language (OCL) 或者Object Query Language(OQL)。
支持对象主键:大家都知道在关系型数据库中,主键可以用来唯一标识一条数据记录。面向对象的框架中也应该有一个对象主键来唯一标识一个对象。
支持事务:创建还必须支持事务,一个交易必须是原子级别的,或者完全成功,或者完全失败,支持类似于数据库的提交和回滚操作。交易结果要求是一致的、独立于其它交易。
支持XML:随着XML这种元数据语言的越来越广泛的应用,框架必须能从XML文件中存取对象。
性能能够被优化:比如如果一个面向对象框架默认产生的sql如果性能不高的话,应该允许用户使用手写的sql来提高性能。
应该支持多种应用:应该即支持桌面型应用开发,也能支持C/S和多层数据库开发以及Web开发。
应该是数据库及数据存取API无关的:可以随时切换开发及数据库发布平台。
应该是兼容现有的数据感知组件的:这样在使用面向对象开发框架改动已有系统时,可以保证平滑的移植。