基于复杂对象的数据快速访问方案的设计与实现*
2012-06-07周微民
周微民
(中国电子科技集团公司第二十八研究所 南京 210007)
1 引言
目前的应用软件大多通过ODBC、JDBC、ADO、BDE等最原始、最直接的方法访问数据库,或是通过数据库厂商提供的接口访问数据库,这些方式虽然运行效率高,但是在程序中嵌入了大量的SQL语句,使得项目难以维护。如果关系数据模型非常复杂,直接写SQL需要专业的知识,对于企业级应用的开发人员,从头开发自己的持久化层是不可行的。同时由于数据标准、规范的建设滞后于信息系统的发展,各个信息系统中的数据库资源都存在着语义、结构等方面的异构性[1],因此需要对象关系映射层,把数据库访问操作封装起来,提供统一的对象接口,供业务调用。
对象/关系映射技术有多种实现,开源项目有 Hibernate[2]、NHibernate[3]、Castle 框 架。Hibernate是 “对 象—关系映射(Object—Relational Mapping,ORM)模块实现数据持久层的一个优秀的Java组件。ORM元素主要功能是实现实体域对象的持久化并封装[4]数据访问的细节。Hibernate对JDBC进行了非常轻量级的封装,其对象/关系数据库映射,持久化,事务管理,缓存机制的功能很好,但是Hibernate在复杂多表联合数据处理上的能力较弱;对于复杂的多表操作不适合用Hibernate。微软NHibernate是基于Microsoft.NET的O/R Map2ping持久化框架。它从数据库底层来持久化.Net对象到关系型数据库。它不仅管理.NET类到数据库表的映射,还提供数据查询和获取数据的方法[5]。但是其中的对象也只是相对比较简单的主表和几张子表之间关联的对象,对象间的复杂关联无法体现出来。Castle框架是针对.NET平台的一个非常优秀的开源项目,从数据访问框架ORM(Object2Relational Mapping,对象关系映射)到IOC(Inversion of Cont rol,控制反转或者叫依赖注入)容器,再到WEB层的MVC框架,基本包括了整个开发过程中的所有内容,为开发易扩展、可伸缩、灵活、健壮的软件系统提供了一个很好的平台[6]。Castle封装了NHibernate的大部分烦杂细节,不需要像NHibernate那样去编写复杂的对象映射文件,配置少且灵活,但是无法支持大型系统复杂的数据库逻辑。
针对上述不足,本文设计了复杂对象模型以及基于该对象模型的数据快速访问方案,采用这种方法进行数据库应用系统开发,将增强系统的数据库访问能力和对软件环境的适应能力,当系统更换底层数据库系统,或更改数据库物理表和字段信息时,只需修改对象和数据实体的映射关系,不会对系统产生大的影响。
2 方案设计
2.1 复杂对象模型构建
为了屏蔽数据库,采用持久化技术。持久化技术的基本思想是以用面向对象的技术将数据库关系表以及表中的记录都看成是可以持久的对象。在这种技术中,首先可以利用面向对象的思想,“持久化”包括和数据库相关的各种操作,并建立其对象模型。例如,保存:把域对象永久保存到数据库;更新:更新数据库中的域对象的状态;删除:从数据库中删除一个域对象;加载:根据特定的OID,把一个域对象从数据库加载到内存;查询:根据特定的查询条件,把符合查询条件的一个或多个域对象从数据库加载到内存中[7]。本文根据持久化思想设计了业务对象模型。
业务对象模型是基于元数据库的,元数据库主要用于管理元数据。元数据是数据的组织、数据域以及关系的信息,也就是数据的数据[8]。元数据库主要存储了用户需要访问数据的相关数据对象的描述信息,构成数据库逻辑视图,其中数据库结构信息主要来源于数据字典,即数据库中用于存储数据库对象结构信息的专用表和视图。
业务对象主要描述业务操作的数据访问视图,以XML的方式展现,具体内容包括:
1)对象信息:对象类名称、对象类描述、数据库对象ID、对象状态、对象类型;
2)对象关系映射信息:对象属性信息、映射的数据库信息;
3)对象关联信息:对象内部表间的关联描述、对象间的关联描述;
4)对象操作信息。增删改查的命名SQL:SQL名称、SQL描述、SQL中的参数描述(包括参数名称、类型)、SQL的输出字段别名名称。级联操作描述:在增加、修改、删除记录操作之前和之后执行的各种命名SQL描述,SQL执行顺序号。
复杂对象是基于业务对象的,是简单业务对象间的关联关系组合。简单业务对象间的关联关系包括两类:
1)如果一个简单业务对象A的删、改、查操作的任一条件字段的值能够包含在另一个简单业务对象B的查询结果中,可以认为B与A之间存在父子关系;
2)如果两个简单业务对象A和A′,都是简单业务对象B的子对象,则可以认为A和A′存在兄弟关系。
2.2 基于复杂对象的数据访问
对象化数据访问主要由业务对象和数据访问两个部分组成。业务对象根据实际应用的数据需求分为简单业务对象和复杂业务对象,主要存储对象和数据库表之间的映射关系;数据访问主要通过动态加载业务对象来完成用户对数据库数据的操作。
对象化数据访问的主要工作流程为:先抽取专业数据库结构到元数据库中,形成数据库逻辑视图;再利用元数据库生成简单业务对象,描述业务操作的数据访问视图;然后分析生成的多个简单业务对象间的关联关系,根据业务需要设置对象间的关联关系生成复杂业务对象,描述业务流程的数据访问视图;最后完成对象的数据访问。
2.2.1 业务对象的生成
业务对象是依托元数据库的,所以要先构建元数据库,然后再生成业务对象。
1)抽取元数据
根据数据模型的描述,从专业数据库的数据字典读取需要访问数据的相关数据对象(包括数据表、字段、约束等)的描述信息,存入元数据库中,为业务对象的生成提供支持。主要步骤如下:
(1)读取专业数据库的连接信息;
(2)读取专业数据库里表的描述信息;
(3)读取专业数据库里表字段的描述信息;
(4)读取专业数据库里表的关联信息;
(5)将专业数据库的元数据描述信息存入元数据库,供生成业务对象时使用。
该操作需要了解数据模型的人员参与选择数据表和其他对象的范围,需要根据应用要求增加或修改表的关联关系或字段的取值范围等,保存在元数据中,供后面生成对象时使用该逻辑关联。对专业数据库的元数据描述包括:
(1)数据表信息:表名称、字段组成、主键字段;
(2)字段信息:字段名称、字段类型、字段长度、是否非空;
(3)关联关系:主子表的关联信息。
2)生成简单业务对象
从元数据模型中读取数据表信息及其关联表信息,以人机交互方式供用户选择与具体业务操作相关的一组表及其关心字段;根据用户选择的表和字段信息,及其元数据描述,自动生成对表间关联关系、读取顺序的描述,以及默认的级联增删改查操作的SQL语句。允许用户以人机交互方式修改默认生成的SQL语句,支持SQL的修改、增加、删除,支持以参数形式定义SQL查询条件,保存业务对象信息到XML中。具体操作流程如图1所示。
3)生成复杂业务对象
根据分析的2.2.1节中用户定义的一组简单业务对象的关联关系,生成对象树。可能存在多棵对象树;根据对简单业务对象树的深度和广度两种遍历方式,生成供用户参考的对象访问操作执行顺序链表。用户通过人机交互方式确定业务工作流程中可能存在的一种或多种对象操作的访问操作执行顺序,还可以给出选择某种执行顺序的条件或优先级;与某个工作流程相关的一组简单对象,构成复杂业务对象,同样以XML存储,XML中包含以下信息:
(1)包含的简单业务对象列表,引用位置。
(2)描述简单业务对象间的父子关系或兄弟关系,描述建立上述关系的表和字段。
(3)描述简单对象访问操作的执行顺序,及选择某种执行顺序的条件或优先级。
2.2.2 数据访问
图1 生成简单业务对象的过程
数据访问主要提供数据库中各类对象的数据访问操作、查询优化[9]以及连接池管理。数据访问操作包括查询、增加、修改和删除,接口类型为对象类型。查询优化主要包括查询预取队列和关键对象缓存:根据复杂业务对象描述中对象操作的执行顺序,抽取执行操作序列中的查询操作,形成查询预取队列;在50%以上的复杂业务对象中存在,且至少存在于两个复杂业务对象中的简单对象称作关键对象,将关键对象存储在内存中形成关键对象缓存链表。连接池管理主要管理数据库的连接,保证数据库资源的合理分配。
根据应用的对象接口请求执行对象的增删改查操作,具体操作流程如图2所示。
图2 对象数据访问及优化的流程
1)如果是查询操作,步骤如下:
(1)如果查询对象不在缓存中,则从数据库获取查询结果,反射成对象集,如果该对象在关键对象缓存链表中,则将对象集数据驻留在缓存中;再根据查询预取队列,获得下一个对象查询操作,利用空闲时间提前执行。
(2)如果查询对象数据已经在缓存中,则不访问数据库,直接从缓存中获取对象。
(3)然后操作对象本身及其关联的对象。
2)如果是对象的增删改操作,则根据复杂对象文件的级联配置执行级联操作,提交数据库。如果未设置级联关系,则执行单表操作,提交数据库;如果执行增删改操作的对象是关键对象,则还需根据增删改结果更新缓存中的对象数据。
3 关键技术
在对象关系映射系统中,对象预取与缓存技术可以提高用户对持久化对象的访问效率。
3.1 查询预取
通过某种策略预测将来可能会被访问到的对象,并预先将这些对象读取到客户端。如果预测对象在后面确实被访问到了,那么预取策略会有效的减少数据访问到数据库查询对象的操作,提高数据访问性能。相反,如果预取对象没有被访问到,则会降低系统的性能,所以制定合理的预取策略是至关重要的。
本方案是通过抽取复杂对象操作序列中的查询操作形成查询预取队列来构建预取策略的。在生成复杂对象的过程中,用户可以使用和修改定制默认生成的简单对象间关联关系,根据复杂对象中关联关系的描述,可以构建出多个查询预取队列。因为用户根据实际数据需求参与关联关系的确定,所以查询预取队列中的对象被访问的机率是很大的甚至是100%。当用户查询某个对象A时,后台会继续查询队列中的下一个对象B,当操作到对象B的数据时,后台会继续查询B的下一个对象C的数据,以提高查询的速度。当用户获取到一个对象查询数据后,可以在内存中获取队列中下一个对象的数据,减少了再去查询数据库的时间。
3.2 关键对象缓存
在实际应用中,频繁地访问数据库,会对应用的性能造成很大影响。为了降低访问数据库的频率,可以把需要经常被访问的业务数据存放在缓存中,并且通过特定的机制来保证缓存中的数据与数据库数据同步[10]。本方案的缓存思想是抽取所有对象中的关键对象形成缓存对象链表,对链表中的对象数据进行本地缓存和实时更新。在用户的第一次查询中,如果发现查询对象是链表中的关键对象,则将查询结果对象驻留在内存中,供其它应用再次查询时直接使用,减少访问数据库的时间。当用户通过关键对象的修改接口更新关键对象的数据到数据库后,数据访问也同步更新缓存中的关键对象数据,保证内存块中关键对象的数据最新。
4 应用示例
复杂对象的数据访问在某项目中的使用示例步骤如下:
1)用户抽取业务数据库模型到元数据库中,形成数据库逻辑视图。
2)基于元数据模型,生成交通设施对象,选择关心的一张主表交通设施及其关联表,选择主表中所有字段和关联表中名称字段,自动生成关联的查询SQL,主子表级联操作的增删改SQL。
生成桥梁对象,选择表中的字段交通设施内码、桥长、桥宽、水深、归属地区、可停靠船的最大吨位等,再在提示的关联表中选择交通设施表,选择关联属性交通设施名称,自动生成关联的查询SQL,主子表级联操作的增删改SQL。类似地生成机场对象。
生成人防设施对象,用户通过业务对象生成工具浏览专业库中的数据表,选择关心的一张主表人防设施表,选择表中的字段人防设施内码、防护等级ID(关联防护等级表)、建筑面积、管理单位、可储藏人数、其它描述,质量现状ID(关联质量现状表)等,再在提示的关联表中选择防护等级表、质量现状表,选择关联属性防护等级名称字段和质量现状描述字段,自动生成关联的查询SQL,主子表级联操作的增删改SQL。
3)由2)生成的4个对象构建的树形成复杂对象公共设施,构建两个查询预取队列:查询11、查询12、查询13和查询21、查询22,如图3所示。针对制作好的一系列对象生成对象接口动态库文件,用户调用对象的增删改查接口用于数据访问。
图3 对象间的关联关系
4)数据访问根据复杂业务对象公共设施描述中对象操作的执行顺序,按照查询11至查询13或查询21至查询22的顺序查询和预取对象数据,形成查询预取队列;设置交通设施对象为关键对象,常驻内存中,以提高这个对象的数据访问速度。
5)按照图3所示的流程,按查询11至查询13的查询操作序列查询交通设施对象,查询数据库返回结果,反射成交通设施对象集,根据预取队列的描述,利用空闲时间提前执行下一个对象桥梁对象的查询操作,然后用户可以操作交通设施对象及其关联子对象桥梁,当操作桥梁数据时,再提前执行下一个对象机场对象的查询。因为交通设施为关键对象,因此该对象数据驻留在内存中。如果用户更新了交通设施这个对象中的数据,数据访问同时也要刷新驻留在内存的交通设施对象数据。
5 结语
通过复杂对象化数据访问,使专业人员将精力集中在业务逻辑处理上,不必关心数据库底层操作的细节。由于数据访问中的对象尤其是带有业务流程的复杂对象是综合了军事指挥控制领域应用的数据访问需求提炼出来的,所以具有一定的通用性,该系统可以应用到指控领域的各个项目中去,大大提高项目的开发效率和可扩展性。
[1]吴姗姗,彭向阳.基于XML的通用数据库访问引擎的设计与实现[J].指挥信息系统与技术,2010(1):55-59.
[2]Christian Bauer,Gavin King.Hibernate in Action[M].USA:Manning Publication,2004:15-26.
[3]Pierre Henri Kuaté,Christian Bauer,Gavin King.NHibernate In Action[M].Manning Publications,2007:36-40.
[4]高昂,卫文学.基于Hibernate与Struts框架的数据持久化应用研究[J].计算机应用,2005,25(12):2818-2819.
[5]李斌勇,李庆.基于NHibernate的ORM映射机制研究[J].计算机技术与发展,2009(7):32-34.
[6]万长鹏,唐慧佳.基于ASP.NET+Castle框架的旅游管理系统的设计[J].成都信息工程学院学报,2007(4):458-461.
[7]周浩,张祖平.面向对象的持久化技术的研究与实现[J].企业技术开发,2010(9):4-5.
[8]武亚青.数据共享环境研究[J].指挥信息系统与技术,2011(2):35-40.
[9]Ben Wiedermann,William R C.Extracting queries by static analysis of t ransparent persiste nce[J].ACM SIGPLAN Notices,2007,42(1):199-210.
[10]孙卫琴.精通Hibernate:java对象持久化技术详解[M].北京:电子工业出版社,2005:173-176.