摘 要: 结合Wrapper Facade模式,给出OCCI程序访问Oracle SpATIal的一般过程,并给出实例。
对象关系数据库管理系统(ORDBMS)是面向对象技术与传统的关系数据库相结合的产物。ORDBMS在原来关系数据库的基础上 ,增加了一些新的特性 ,这些特性对查询优化影响很大。查询处理是ORDBMS的重要组成部分 ,它的性能优劣将直接影响到DBMS的性能 。在当前众多的ORDBMS中,越来越多的GIS系统采用Oracle SpaTIal管理地理数据。目前访问Oracle数据库的方式有很多种,而这些方式或因为追求通用性而牺牲效率,或因为不能适应地理数据类型特点而无法实际采用。
针对上述问题,本文探讨了通过设计OCCI程序访问Oracle Spatial中地理数据的一般过程。由于OCCI程序在代码级上具有类级封装,因此具有灵活、高效、代码简洁、易于理解和维护的优点。OCCI在引入面向对象分析和设计技术后,有利于实现进一步封装,在封装边界上限定软件元素的共生性,产生更健壮、更可靠和更易维护的软件模块。同时,本文采用Wrapper模式向外提供一个简单一致的界面,降低外部程序对功能实现部分的直接依赖。
1 几何对象在Oracle Spatial中的表示
ORACLE SPATIAL 是 Oracle 数据库强大的特性,包含了用于存储矢量数据类型、栅格数据类型和持续拓扑数据的原生数据类型。ORACLE SPATIAL使得我们能够在一个多用户环境中部署地理信息系统(GIS),并且与其它企业数据有机结合起来,统一部署电子商务、政务。有了 ORACLE SPATIAL 之后,即可用标准的 SQL 查询管理我们的空间数据……该方案中,能由上述对象关系模型所表示的空间对象被存储在由用户定义的数据表的单个数据域列中。该数据域的数据类型是几何对象类型SDO_GEOMETRY。对象类型SDO_GEOMETRY的定义如下:
CREATE TYPE sdo_geometry AS OBJECT (
SDO_GTYPE NUMBER,
SDO_SRID NUMBER,
SDO_POINT SDO_POINT_TYPE,
SDO_ELEM_INFO
MDSYS.SDO_ELEM_INFO_ARRAY,
SDO_ORDINATES
MDSYS.SDO_ORDINATE_ARRAY);
其中:SDO_GTYPE描述地理对象的类型,SDO_SRID用以确定所采用的坐标系,SDO_ELEM_INFO用以定义对象组成元素的信息。
2 OCCI
OCCI(Oracle C++ Calling Interface)是Oracle公司推出的专为访问Oracle数据库的API类库,它为用户提供了一个底层二次开发环境。通过OCCI,用户可以开发自己的程序,灵活、高效地访问Oracle数据库,获取数据库管理系统的支持,完成对数据的访问。
2.1 OCCI的优势
OCCI本质上是对OCI代码的类级封装。因此在继承了OCI强大功能的基础上,OCCI在访问Oracle方面还具有许多新的特性:
(1)封装了复杂的实现细节,提供了一致的调用接口。代码简洁有力,程序易于开发、理解和维护。
(2)引入面向对象的设计和编程技术,使编写的程序更健壮、可靠、可扩展、易复用和易维护。
(3)由于具有类级封装,所以有利于在封装的边界上限定软件元素的共生性,使得开发的程序更健壮、可靠和易维护。
类级封装改变了从前的OCI代码难理解、难维护的缺点,为更好地解决软件中的共生性创造了条件。共生性(connascence)是指在一定的环境下,软件元素间为适应某种变化、保持正确性而需要进行的一些变化。但如果采用正确的面向对象设计方法,可以增强封装体内部的聚合质量,降低它们之间的耦合程度,产生封装边界内共生性化、边界间共生性化的较佳设计效果。这样产生的软件模块具有健壮、可靠、易扩展、易复用和易维护的特点。
2.2 OCCI应用程序生成机制
第三方应用程序通过与OCCI类库进行连接生成OCCI应用程序(OCCI Application)。通过获得Oracle数据库管理系统服务(Oracle Database Server)的支持,OCCI应用程序支持所有的SQL数据定义、数据操纵和事务处理功能。
2.3 一般对象访问流程
OCCI进行对象访问的流程为:(1)采用对象模式初始化程序环境。(2)取得对象的一个拷贝存到用户端的缓存中。(3)在该缓存中操纵对象。(4)如对该对象拷贝进行了设置操作,则将该拷贝置为Dirty。(5)如果需要,用修改过的对象拷贝刷新数据库中的对象。
3 Wrapper Facade模式封装OCCI代码
3.1 Wrapper Facade的意图和一般结构
Wrapper facade模式的意图是采用面向对象类的接口对底层函数和数据结构进行封装,以产生简洁、健壮、可移植和易复用的应用程序模块。本文应用环境下,虽然OCCI对OCI进行了类级别的封装,但在具体应用程序中,开发人员仍然要根据应用需要编写OCCI代码序列。常见的Wrapper facade pattern的应用实例有MFC、ACE以及AWT,它们都封装了操作系统的C代码API函数。
该模式一般结构示意图和动态结构用UML的类图和顺序图分别表示的情况。模式中主要的成分有:(1)函数,封装了已有的底层函数和数据结构序列,这个序列提供一个内聚的功能服务。(2)包装界面(Wrapper facade),由包含一个或多个类的集合构成。这些类封装了上述函数及其相关的数据结构,通过类中的方法来组织上述函数。用户通过对包装界面类的方法调用进而获得对底层代码序列的调用。
面对底层代码,一个缺乏封装单元的系统存在共生性泛滥的问题。面向对象的设计方法强调在封装边界内将共生性化,在封装边界间将共生性化。Wrapper facade模式正体现了这种思想。它实际上是软件设计中不断重复的一条分类准则,即将相似的东西放在一起,将不相似的东西分开存放。分类后的模块功能专一、变更波动小,这样就产生了健壮、可靠、易复用和易维护的代码结构。
3.2 采用Wrapper Facade Pattern的一般步骤
采用Wrapper facade模式主要是一种分类的思路。利用界面类实现各个代码序列的封装一般分为以下三个步骤:
(1)对现有的函数和数据结构进行划分,确定它们之间内聚的抽象和关系(cohesive abstractions and relationships)。
(2)按以上分析和划分,实现具体分组,将相关底层函数和对应数据结构序列用类的结构聚集起来,以类的方法和形式存在。
(3)定义对应的异常处理机制。
4 设计OCCI程序访问Spatial的一般过程
结合用Wrapper facade pattern进行设计的一般步骤,设计OCCI程序访问Spatial的一般过程可以分为以下三个步骤:
(1)分析需要完成的功能,确定OCCI函数及其相关数据结构序列的内聚分组。
一个OCCI程序大致要完成以下功能:
①建立和断开数据链路连接。
②从数据表中选取一条记录。
③向数据表中插入一条记录。
④向数据表中更新一条记录。
⑤从数据表中删除一条记录。
⑥设置地理几何对象内容。
以上除设置地理几何对象内容功能外,其余功能可归为事务处理类。从功能内聚来看,至少要有三个类分别完成事务处理、对象设置以及异常处理。
(2)实现具体分组,定义内聚的类(cohesive classes),将函数序列封装到类的方法中。
一个OCCI程序中可以定义二个类。类address_obj负责对对象内容赋值,类occipobj负责事务处理。具体定义形式如下:
//设置对象值
class address_obj :public sdo_geometry
{
public :
address_obj(sdo_geometry类型对应的参数)
{ //产生一个address_obj的实例}
} ;
其中,sdo_geometry是按spatial中MDSYS.SDO_Geometry生成的对应C++类。
//事务操作
class occipobj
{private :
//属性数据
public :
occipobj(string UserName,string Password,string DBLink);
//构造函数建立数据连接
occipobj();//析构函数断开数据连接
setTableName(″数据表名″);
//选择当前操作的数据表
sdo_geometry*GetOneRow(选取信息);
//选取一条记录
InsertRow(插入信息);//插入一条记录
};
(3)考虑异常处理,即考虑类address_obj和occipobj捕获异常后的异常处理。
5 应用举例
下面给出使用上述一般设计过程产生的OCCI主程序,在进行地理数据操作(如写入、读出)时的一个实例。
void main(void)
{string user=″username″;
string passwd=″password″;
string db=″database_path″;
try {
occipobj*demo=new occipobj(user,passwd,db);
demo->setTableName(″数据表名″);
/*写入之前要构造一个具体的对象*/
sdo_geometry obj(……);
demo->insertRow(obj,其他信息);
/*读出时,首先获取Mdsys.sdo_geometry字段的定位信息,
一般用指针来表示*/
sdo_geometry*pObj=demo->GetOneRow(定位信息);
/*在这里可以对pObj进行必要的操作*/
delete (demo);}
catch(SQLException &sqlExcp)
{cerr<<<″:″<
sage() 《 endl;}
catch(exception &excp)
{cerr 《 excp.what() 《 endl;
}}
由此看出经过Wrapper facade封装得到的代码结构简洁清晰,更易理解和维护。
6 结 论
本文提出了OCCI程序设计的一般步骤,并给出了一般的应用情况。采用本文的一般过程设计的OCCI程序约束了软件结构中共生性的问题,使得产生的代码具有简洁清晰、健壮、易理解、易扩展、易复用和易维护的特点。
免责声明: 凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处。非本网作品均来自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。