Tony Gong的技术Blog  
技术旅途中蹒跚的行者

本文是写在公司部门的网站上的,我懒得作改动了,直接copy到blog上,当中可能有很多不清楚的地方,望谅解。


早上开摩托车的时候突发奇想,假如出于某种原因,我们现在的XXX产品要把数据库换成其他数据库(比如Oracle,db2等),原因嘛,可能是“客户不满sql性能?Oracle白送?sql涨价?Microsoft倒闭?客户是Oracle老总的儿子?”,真的要这样做的话,会发生什么呢?

 

首先,这肯定是一场灾难,估计一堆人要吐血身亡了。

 

当然,吐好血之后,就要考虑怎么解决问题了。

 

由于我们现在XXX(群体替换,应该没漏网之鱼)产品的架构很完美(恩,先拍下马屁)。不知道当初前辈门设计的时候是否已经考虑过这个问题,或者是单纯为了分层,总之,现在的DataAccess layer相对独立,对于替换数据库是很有利的。

 

先看看现在的一个业务的简化流程:

 

 

前面的不看了,看后面的。我的理解如下:

1,业务逻辑层(处理一个具体的业务,比如:<增加一个生徒>这个业务,该业务调用了数据层的诺干个方法,包括AddStudentInfo(),AddStudentEducationInfo()等)

 

业务层可以调用诺干个DA的诺干个方法,完成这个业务。

顺便说一句:我们现在的XXX产品,业务层几乎形同虚设,把所有的业务逻辑都写到了DA层中。这就导致了DA层的臃肿,难维护(谁知道那几百行的一堆sql代码是怎么干活的啊),代码复用难(几乎是不用想了)。

最理想的状态当然是DA层只处理单一的,具体的一个数据库操作,比如增加生徒基本信息,增加生徒家庭信息,增加生徒教育信息,查询生徒基本信息等等。

然后在BR层中,根据业务的不同需要,组合调用不同的DA

 

当然,以上仅仅是理想状态,可能很难实现….

 

2,数据层(这层是处理一个具体的数据库操作,比如增加生徒基本信息AddStudentInfo(),在这里组织一下sql语句,或者使用存储过程,传入SqlHelper.vb,进行数据库操作)

 

3SqlHelper.vb:这个是Microsoft DataAccess Application Block提供的一个数据库操作类,对指定数据库进行操作

 

DAAB的早期版本(v2.0)只包含了SqlHelper,但后来微软发布的Petshop3.0&4.0(Microsoft用来炫耀.net能力的事例程序)已经包含了OracleHelper

 

到了v3.1,DAAB支持的数据库更多,而且使用起来更方便。

 

 

废话不多说了,转入正题,该怎么换数据库呢?假如换成Oracle,我们的结构发生如下变化:




 

我们现有的Sql 数据层不需要做改动,只是额外增加一个Oracle数据层。哪天客户心血来潮,完全可以再换过来…..

 

要做的改动如下:

 

1,增加IDAL,把sql DA 抽象出来,放到IDAL中,以便增加其他数据层时,可以有个规范。

 

工作量一般吧。

 

 

2,增加一层,DALFactory,运用到了Abstract Factory Method。这部很重要,该层的作用是,根据配置信息(或其他途径),反射具体的DALsql or oracle)。

 

这个工作量也不是很大的。不过鉴于我们XXX产品DA层的庞大,还是要做一点工作的。

 

3,修改BR层。

原本BR直接就调用Sql DA层:

Dim objDA As New RegularExamDA(Me.activeConn)

。。。对objDA进行操作

 

现在改造一下。需要对接口IDAL进行操作,然后调用DALFactory,DAlFactory会把具体的数据层反射给BR

Private objDA as IRegularExamDA

objDA = DALFactory.RegularExamDAFactory.Create()

。。。。对objDA进行操作

 

工作量也是一般,是辛苦活。

 

4,增加诺干个OracleDAproject ,对应于我们现在的Sql DA

       当然,DA层中的一些sql语法也要做相应的调整。

       比如,(1sql server Getdate()函数取出系统时间,而在ORACLE中是sysdate

2sql server 中用top子句,如select top 10 * from 表名
 
oracle利用rownum,rownumoracle系统顺序分配为从查询返回的行的编号,返回的第一行分配的是1,第二行是2,依此类推,这个伪字段可以用于限制查询返回的总行数。
 
只返回前10条纪录
  SQL> select * from
表名 where rownum<11;

 

这个工作量还是很大的,估计要吐血。

顺便再说一句:我们臃肿的DA又出问题了,那一大堆成千上百行的sql语句要修改成支持oracle,还真是一件很有挑战性的事啊,不知道哪位兄弟姐妹有幸干这活,我为他/她祈祷。阿门!

还有,我们那些sql server上存储过程,Function,也是一个大问题,这些都是和具体数据库关联性极大的冬冬,移植起来肯定很麻烦。尤其我记得早期的Mysql 是没有存储过程的…..

 

我的建议是,尽量少用数据库的这些功能。存储过程都放到DA去,在DA里些sql语句。Function也不要用,在我们的程序里用其他方法代替吧。

 

对于在开发中是否充分使用数据库的特性,一直有2种不同意见。一些人认为,数据库的这些特性差异性太大,造成移植性极差,而且很多程序员只对一种数据库比较熟悉,假如换数据库的话,光学习这些特性就要花不少代价。

另一种人却认为使用数据库的特性,能提高开发效率,提高程序性能,and 其他一堆好处。

 

具体用哪种,请视具体情况。不过显而易见,我是前者的拥护者,呵呵。

 

5,增加OracleHelper.vb,和sqlhelper放一起吧,对照下sqlhelper,不需要改多少东西的。

 

这个没啥工作量

 

 

 

至此,改造差不多完成了,问题。。。。应该还是有的。

 

将来要换回sql,只需要修改配置文件(或者在login画面加选项)。恩,用户可以每天换一个数据库了。

 

假如还要增加一个其他数据库(db2,Sybase,mysql?),只要增加一个XXXDA,然后继承IDAL,写出相应的DA代码,就可以了。

 

同时,用户也可以同时使用数个数据库,比如生徒放sql,教师放Oracle,完全没有问题的。

 

当然,我们XXX产品是不太可能换数据库的,不过对于其他项目同样适用。

比较诱人的是,只要把这个架构搭建好,不管将来的项目用何种数据层,都可以套用。

 

 

付上最新版的DAAB(v3.1):

http://www.gotdotnet.com/workspaces/releases/viewuploads.aspx?id=c20d12b0-af52-402b-9b7c-aaeb21d1f431

 

已经不在分sqlhelper,oraclehelper了,由AdoHelper自动选择合适的数据库连接类来连接,支持SqlServer, Oracle, OleDB, ODBC不同类型的连接。

 

水平有限,文中一堆错误需要指正。谢谢。

 

posted on 2007-02-06 10:15  Tony.Gong  阅读(1053)  评论(2编辑  收藏  举报