通用数据访问模式的研究
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1本课题得到云南省自然科学基金资助项目(2005IT17)。 -1-
http://www.paper.edu.cn
对象技术中的设计原则:Liskov 原则[3]。通过上面的设计,我们的数据访问的代理模式如 图 1。这些数据库操作按其使用功能,可分为两类:一类是数据库的连接与释放,我们定 义为connect()和close()方法。另一类是对数据的具体操作,这些操作有:数据的查询、删除、 修改、添加功能(execSelectSQL()、execDeleteSQL()、execUpdateSQL()、execInsertSQL()) 以及事务的处理(begineTrans()、commit()、rollback())等(如图 1TableSubject所示)。而 在具体的RealTableX中我们屏蔽了这些操作。
上述的 RealTableX 类为具体业务表类,实际操作中会随着业务的变化而增加或者废弃 一些不需要的数据表,为了适应这种需求的灵活性,我们使用统一的接口来替代 RealTableX 对象,让所有客户使用代理只针对一个接口来访问,而让所有其他的数据库表都继承这个 接口,我们将这个统一的接口命名为 DBTable。这一改变正是应用了面向
public int connect (); public int close (); public int execInsertSQL (DBTable table); //other useful methods } 最后,在客户端,我们根据需要生成各中代理,通过代理执行各种操作,在这里我们 通过调用各具体数据库表类(RealTableX)的查询获取方法实现各种数据操作,从而与代 理模块无缝的结合起来。客户端的代码片断如下所示: DBTable table = new RealTable1();
return new OracleOraProxy(); } public OracleProxy createOracleMSProxy(){
return new OracleMSProxy(); } public Dwk.baidu.com2Proxy createDB2IBMProxy(){ //此处屏蔽此方法实现,在 DB2Creator 中 //同理屏蔽创建 Oracle 代理的方法
在具体应用中,当系统更换RDBMS或数据库驱动程序时,我们只需利用OracleCreator 或DB2Creator来重构[5]生成不同的数据库厂商代理,然后通过生成的各种代理来访问具体 的数据库表。在访问时我们利用统一的接口DBTable类,这样屏蔽了具体的数据库表类, 从而提高了系统的复用性。
3.框架的实现
2. 框架的设计
为了编写可复用、可维护性好的代码,人们在实践经验中逐渐探索出了一些有针对性 的设计方案,而这些设计方案经过人们反复利用与修正,最终形成了某个特定场景下一般 问题的解决方案[2],即我们现在通常所说的设计模式。本文所研究的就是数据访问这一特 定的应用场景下,实现支持多种RDBMS的通用数据访问的解决方案。在此框架中我们需要 用到两种最常用的设计模式:Proxy模式和Abstract Factory模式。
关键词: 复用; 设计原则; 代理模式; 工厂方法模式
中图法分类号: TP311
文献标识码: A
1.引言
随着计算机的广泛应用,各行各业的企业都加速自身的信息化建设。大多数信息系统 都不可避免地涉及到数据的存储及访问,有效且优质的数据访问代码,对于现实中任何企 业应用程序的性能和适用性来说,都是至为关键的。要改进现有系统,没有哪种方式比优 化数据访问代码更好了[1]。
一般大中型企业中都会有一些早期开发的遗留系统,在对不同系统的整合过程中,会 涉及到调用不同数据库的数据。将企业的业务逻辑与数据访问隔离开来就成为了一个关键 的工作,这样当后台数据库发生变更时,不至于引起客户端程序的大量改动,从而保证了 系统的整体的稳定性与数据访问程序的可移植性。据此,本文提出了一个集中控制且支持 多种数据库平台的数据访问模式。
为了能在保证系统不变性的前提下支持异构数据库管理系统,此模式的 TableProxy 类 必须能够实时的被替换,而其具有的功能没有任何的改变,即实际上我们的系统中有多个 TableProxy,如 OracleProxy、SQLProxy 等。为了能够达到这个目的,我们引进 Abstract Factory 模式。
2.2 应用 Factory Method 设计数据库连接模块
通过上节的分析我们很容易地将数据库与应用程序隔离开来,屏蔽了关系型数据库与 面向对象的差异,实现了面向对象应用中透明地操作数据库表。对保护数据的安全也有一 定作用。
为支持多种RDBMS的联机数据提供程序,我们采用工厂方法 (Factory Method)模式[2], 利用工厂方法我们创建不同的数据库访问代理。以下我们定义生成不同代理对象的各种角 色。 1) 创建者接口(Creator):用于声明创建不同代理的工厂方法。在本框架中我们将其命名 为 DatabaseCreator。DatabaseCreator 接口只定义了各种不同数据提供程序的实例操作,与 具体应用无关,而真正创建这些实例的操作在实现这个接口的子类中。 2)具体创建者类(Concrete Creator):实现创建具体代理对象。任何一个具体创建者必须 实 现 创 建 者 接 口 DatabaseCreator , 这 是 本 模 块 的 核 心 部 分 , 包 括 OracleCreator 和 DB2Creator。在本框架中的具体创建者类必须实现 DatabaseCreator 接口中的工厂方法,用 来创建针对各种不同数据库厂商的代理。如本例的针对 Oracle 的不同数据驱动程序的两种 代理 OracleOraProxy 和 OracleMSProxy 以及针对 DB2 的不同数据 驱动程序的 代理
http://www.paper.edu.cn
通用数据访问模式的研究1
陈卫,丁志强,徐劲松
昆明理工大学信息工程与自动化学院,云南昆明(650051)
摘 要: 运用面向对象的设计原则,将代理模式与工厂方法模式相结合,提出了一种新的 通用数据访问模式。该模式能够支持多种关系型数据库管理系统和数据驱动程序,通过将 应用层与数据层隔离,大大减少了系统的耦合性,具有广泛的实际应用前景。
2.1 应用 Proxy 设计框架
根据Proxy模式的机制,我们需要建立三组类[4]:由关系型数据库表映射成的具体处理 业 务 的 数 据 对 象 RealTableX , 用 来 接 受 来 自 所 有 客 户 端 的 数 据 访 问 请 求 并 将 其 转 发 给 RealTableX的代理对象TableProxy和为保证代理对象具备代理数据对象的功能,即能在任何 时候能“替代”RealTableX对象的统一接口TableSubject。
-4-
http://www.paper.edu.cn
DatabaseCreator factory=new OracleCreator(); //生成代理类,重构在以下进行。 //OracleProxy oracleMSProxy = factory.createOracleMSProxy(); OracleProxy oracleOraProxy = factory.createOracleOraProxy(); oracleOraProxy.connect(); oracleOraProxy.execInsert(table); oracleOraProxy.close();
-2-
http://www.paper.edu.cn
DB2MSProxy 和 DB2IBMProxy。在这里我们可以扩展任意数据库的代理,如可根据实际需 要添加 SQLSrvCreator,来实现 SQL Server 数据库的访问。 3)抽象产品类(Abstract Product):为一类产品对象声明一个接口。本模块中我们的抽象 产品类为 OracleProxy 和 DB2Proxy 接口。它们提供连接数据库的各种操作以及转换操作的 结果等功能的定义,本模块中的抽象产品接口实际上就是上节图 1 中的 TableProxy,稍后 我们具体论述。 4)具体产品类(Concrete Product):实现抽象产品中定义的所有接口。在具体产品中的接 口方法由各种数据库厂商或第三方的数据驱动程序支持。这些驱动程序可以是同一数据库 的不同厂商提供的(如对于 oracle 数据库的驱动程序有 oracle 自己提供的 OracleInProcServer 和 MS 提供的 OracleClient),也可以是不同数据库的统一厂商提供的(MS 提供的 OleClient 和 OracleClient)。所有这些具体产品类都实现抽象产品类定义的操作以达到支持不同 RDBMS 和不同数据库厂商的数据驱动程序。从而极大地增强了数据库替换的灵活性和可 维护性。
在这里我们对数据库的连接模块给出本框架的 java 实现代码。首先在 DatabaseCreator 接口中定义要创建的各种实际可能用到的代理,在这里我们以不同厂商(MS、Oracle、IBM) 的 Oracle 和 DB2 的数据驱动程序为例。 public interface DatabaseCreator { public OracleProxy createOracleOraProxy(); public OracleProxy createOracleMSProxy(); public DB2Proxy createDB2IBMProxy(); public DB2Proxy createDB2MSProxy(); }
} …… } }
而在 OracleProxy 和 DB2Proxy 中我们定义了数据库的连接和各种操作。真正的操作则 通过各厂商的驱动程序实现的具体代理(如 OracleOraProxy)中实现。OracleProxy 代码如 下(DB2Prxoy 同): public interface OracleProxy{
通过以上角色的定义,我们已经形成了各种数据库驱动程序实现的不同代理的工厂, 在完成这一模块后,我们需要将其整合到上一节设计的代理模块中去。实际上,我们这一 模块的设计就是完成上述代理框架的 TableProxy 类的功能。在图 1 中,DBTable 类和 TableProxy 类实际上分担不同的职责:DBTable 类(严格来说,应该是各具体数据库表类 RealTableX)负责对每个数据库表类的各字段值的设置和获取以及各种 SQL 语句(如添加、 修改和删除等)的生成;而 TableProxy 类负责数据库的连接以及各种 SQL 语句的执行(包 括存储过程、事务等)。而在我们的数据库代理生成模块中,我们的目的是生成各种数据库 驱动程序实现的代理。而这些驱动程序所要实现的方法就是 TableProxy 类中要实现的功能。 因此,数据 库代理模块中的各种代理如 OracleProxy 类和 DB2Proxy 类就是我们要整合的对象,即这两 个类替换 TableProxy 类。而真正的代理则是由具体创建者类(OracleCreator 和 DB2Creator) 生 成 的 具 体 产 品 类 , 即 具 体 数 据 库 厂 商 代 理 类 (OracleOraProxy 、 OracleMSProxy 和 DB2MSProxy、DB2IBMProxy)。数据库代理生产模块的 UML 图如图 2 所示。
之后在各自的数据库代理中创建代理,在实现创建不同数据库代理时我们可屏蔽掉另
-3-
http://www.paper.edu.cn
一 不 同 数 据 库 ( 此 例 中 的 DB2 ) 代 理 , 具 体 手 段 可 采 用 如 抛 出 异 常 等 。
OracleCreator 的代码: public class OracleCreator implements DatabasCreator { public OracleProxy createOracleOraProxy(){