Heim  >  Artikel  >  Datenbank  >  Winform开发框架中实现多种数据库类型切换以及分拆数据库的支持-

Winform开发框架中实现多种数据库类型切换以及分拆数据库的支持-

WBOY
WBOYOriginal
2016-06-07 15:57:20981Durchsuche

在很多应用系统里面,虽然一般采用一种数据库运行,但是由于各种情况的需要,可能业务系统会部署在不同类型的数据库上,如果开发的系统能够很方便支持多种数据库的切换,那可以为我们减少很多烦恼,同时提高系统的适应性和强壮型。还有一种情况,由于业务数

在很多应用系统里面,虽然一般采用一种数据库运行,但是由于各种情况的需要,可能业务系统会部署在不同类型的数据库上,如果开发的系统能够很方便支持多种数据库的切换,那可以为我们减少很多烦恼,同时提高系统的适应性和强壮型。还有一种情况,由于业务数据库的不断膨胀或者方便数据库的切割隔离,有时候也会把不同的业务数据库进行分拆,如权限提供数据库,客户关系管理数据库,工作流程数据库,企业营运数据库等等,因此在一个系统里面,同时使用2个或者以上的数据库的情况也是有的。针对这两种情况,本文介绍在我的Winform开发框架(也使用我的其他框架),如何具体处理这两个问题的。

在我的各种开发框架里面,底层都是采用同一种数据库的访问方式,就是采用了Enterprise Library的数据库访问模块,这个是微软开源的企业应用模块,里面各种应用模块,都堪称是开发的最佳实践。当然利用里面的数据库访问模块,是很广泛的,这个数据库访问模块,可以通过配置的方式支持多种数据库的变化。因此整合到我的Winform开发框架里面,也很容易实现这种多数据库的方式处理。

Winform开发框架,常见的分层模式,可以分为UI层、BLL层、DAL层、IDAL层、Entity层、公用类库层等等,B/S的Web开发框架也是提供类似的架构模式,它们只是Web界面层有所不同,这样就给我们提供了一个统一性的开发模式,使得开发起来更加高效,统一性更好。框架界面层以下的架构设计图如下所示。

\


1、支持多数据库的设置

1)数据库访问基类的了解

为了介绍支持多种数据库的模式,我们需要先来了解下整个框架的层次结构。喎?http://www.2cto.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+CkFic3RyYWN0QmFzZURBTMrHs+nP88HLy/nT0Mr9vt2/4sq1z9a1xLOsvLa7+cDgoaM8L3A+CjxwPgpCYXNlREFMU1FMysfV67bUU3FsU2VydmVyyv2+3b/isr+31rX31fu7+cDgo6i63NChtcS199X7o6mhozwvcD4KPHA+CkJhc2VEQUxTUUxpdGXKx9XrttRTcWxpdGXK/b7dv+K1xLK/t9a199X7u/nA4KOoutzQobXEtffV+6OpoaM8L3A+CjxwPgpCYXNlREFMTXlTcWzKx9XrttRNeVNxbGl0Zcr9vt2/4rXEsr+31rX31fu7+cDgo6i63NChtcS199X7o6mhozwvcD4KPHA+CkJhc2VEQUxBY2Nlc3PKx9XrttRBY2Nlc3PK/b7dv+K1xLK/t9a199X7u/nA4KOoutzQobXEtffV+6OpoaM8L3A+CjxwPgpJQmFzZURBTMrHy/nT0Lv5tKHK/b7dv+K3w87KwOC1xL3Tv9qhozwvcD4KPHA+Csr9vt23w87KvdO/2sq1z9ay46OoyOdDdXN0b21lcqOpus2907/atqjS5bLjo6hJQ3VzdG9tZXKjqdK70fmjrLa809DSu7j2u/nA4KOsyOe7+dPaU3FsU2VydmVyyrXP1rXEu/nA4M6qQmFzZURBTFNRTKOs1eK49rv509pTcWxTZXJ2ZXK1xMr9vt23w87Ku/nA4KOsy/zSssrHvMyz0NfU0ru49rOsvLa7+cDgo6i087bgyv21xMq1z9bU2tXiwO+jqUFic3RyYWN0QmFzZURBTKGjy/vDx9auvOS1xLzMs9C52M+1yOfPwsv5yr48L3A+CjxwPgo8aW1nIHNyYz0="http://www.2cto.com/uploadfile/Collfiles/20140613/2014061309052829.png" alt="\">

而我们刚才在项目工程的图里面看到,BaseDALSQL、IBaseDAL、AbstractBaseDAL这些类库由于具有很大的通用性,为了减少在不同的项目中进行复制导致维护问题,因此我们全部把这些经常使用到的基类或者接口,抽取到一个独立的类库里面,为了和普通的DotNET公用类库命名进行区分(WHC.Framework.Commons),我们把它命名为WHC.Framework.ControlUtil。

2)多数据库的代码实馅喎?http://www.2cto.com/kf/yidong/wp/" target="_blank" class="keylink">WPC9wPgo8cD4KzqrBy8q1z9a24Mr9vt2/4rXE1qez1qOsztLDx9Do0qrU2sXk1sPOxLz+wO/D5rbByKHP4LnYtcTF5NbDo6y/tL7fzOXKx7m51OzEx9bWuMPK/b7dv+K1xKOsyLu687340NCz9cq8u6+yu82stcSzzNDyvK/A4KOstNO2+Mq1z9a199PDsrvNrMr9vt2/4sDg0M21xMr9vt2/4rfDzsrA4KGjPC9wPgo8cD4K1NpCYXNlQkxMtcRJbml0uq/K/cDvw+a1xMq1z9a0+sLryOfPwsv5yr6hozwvcD4KPHA+CiNyZWdpb24guPm+3bK7zay1xMr9vt2/4sDg0M2jrLm51OzP4NOmtcREQUyy4zwvcD4KPHA+CkFwcENvbmZpZyBjb25maWcgPSBuZXcgQXBwQ29uZmlnKCk7PC9wPgo8cD4Kc3RyaW5nIGRiVHlwZSA9IGNvbmZpZy5BcHBDb25maWdHZXQoJnF1b3Q7Q29tcG9uZW50RGJUeXBlJnF1b3Q7KTs8L3A+CjxwPgppZiAoc3RyaW5nLklzTnVsbE9yRW1wdHkoZGJUeXBlKSk8L3A+CjxwPgp7PC9wPgo8cD4KZGJUeXBlID0gJnF1b3Q7c3Fsc2VydmVyJnF1b3Q7OzwvcD4KPHA+Cn08L3A+CjxwPgpkYlR5cGUgPSBkYlR5cGUuVG9Mb3dlcigpOzwvcD4KPHA+CnN0cmluZyBEQUxQcmVmaXggPSAmcXVvdDsmcXVvdDs7PC9wPgo8cD4KaWYgKGRiVHlwZSA9PSAmcXVvdDtzcWxzZXJ2ZXImcXVvdDspPC9wPgo8cD4KezwvcD4KPHA+CkRBTFByZWZpeCA9ICZxdW90O0RBTFNRTC4mcXVvdDs7PC9wPgo8cD4KfTwvcD4KPHA+CmVsc2VpZiAoZGJUeXBlID09ICZxdW90O2FjY2VzcyZxdW90Oyk8L3A+CjxwPgp7PC9wPgo8cD4KREFMUHJlZml4ID0gJnF1b3Q7REFMQWNjZXNzLiZxdW90Ozs8L3A+CjxwPgp9PC9wPgo8cD4KZWxzZWlmIChkYlR5cGUgPT0gJnF1b3Q7b3JhY2xlJnF1b3Q7KTwvcD4KPHA+Cns8L3A+CjxwPgpEQUxQcmVmaXggPSAmcXVvdDtEQUxPcmFjbGUuJnF1b3Q7OzwvcD4KPHA+Cn08L3A+CjxwPgplbHNlaWYgKGRiVHlwZSA9PSAmcXVvdDtzcWxpdGUmcXVvdDspPC9wPgo8cD4KezwvcD4KPHA+CkRBTFByZWZpeCA9ICZxdW90O0RBTFNRTGl0ZS4mcXVvdDs7PC9wPgo8cD4KfTwvcD4KPHA+CmVsc2VpZiAoZGJUeXBlID09ICZxdW90O215c3FsJnF1b3Q7KTwvcD4KPHA+Cns8L3A+CjxwPgpEQUxQcmVmaXggPSAmcXVvdDtEQUxNeVNxbC4mcXVvdDs7PC9wPgo8cD4KfTwvcD4KPHA+CiNlbmRyZWdpb248L3A+CjxwPgp0aGlzLmRhbE5hbWUgPSBibGxGdWxsTmFtZS5SZXBsYWNlKGJsbFByZWZpeCwgREFMUHJlZml4KTsvL8zmu7vW0Ly2tcRCTEwuzqpEQUwuo6y+zcrHREFMwOC1xMirw/s8L3A+CjxwPgpiYXNlRGFsID0gUmVmbGVjdC5DcmVhdGUodGhpcy5kYWxOYW1lLCBkYWxBc3NlbWJseU5hbWUpOy8vubnU7LbU06a1xERBTMr9vt23w87KsuO1xLbUz/PA4DwvcD4KPHA+CtTavt/M5bXE0rXO8bbUz/O1xLX308O1xMqxuvKjrM7Sw8eyu9aqtcDL/L7fzOXKx7X308PExLj2yv2+3b/itcS0psDtwOC9+NDQtKbA7bXEo6zWu9Do0qq199PDy/y1xLv5tKG907/avs2/ydLUwcujrMjnz8LKx73nw+ay47XEsr+31rX308O0+sLroaM8L3A+CjxwPgovL8m+s/252MGqtcS4vbz+PC9wPgo8cD4KaWYgKCFzdHJpbmcuSXNOdWxsT3JFbXB0eShpZHMpKTwvcD4KPHA+Cns8L3A+CjxwPgpzdHJpbmdbXSBpZEFycmF5ID0gaWRzLlNwbGl0KA==",');

foreach (string id in idArray)

{

InformationInfo info = BLLFactory.FindByID(id);

if (info != null&& !string.IsNullOrEmpty(info.Attachment_GUID))

{

BLLFactory.Instance.DeleteByAttachGUID(info.Attachment_GUID);

}

}

}

在具体的配置文件里面,我们就可以根据需要配置好相关的数据库了。

根据Enterprise Library的配置,我们只要制定了,那么就会获取sqlServer的节点,而代码通过解析ComponentDbType配置项,就可以构造对应的数据库访问对象了。两者合一就可以正确获取到处理对象,并成功处理数据库的访问。

2、支持分拆不同数据库的设置

上面介绍的方式,一次性只能访问一个数据库,因此默认在代码构造数据库访问对象的时候,是通过下面的代码进行的。

Database db = DatabaseFactory.CreateDatabase();

这样每次只会获取defaultDatabase设置的数据库进行构造,如果我们在一个系统里面,同时支持多个数据库的访问,那么我们应该如何处理呢。

在框架的基类AbstractBaseDAL里面,我们对构造数据库的代码进行了封装。

///

/// 根据配置数据库配置名称生成Database对象

///

///

protectedvirtual Database CreateDatabase()

{

Database db = null;

if (string.IsNullOrEmpty(dbConfigName))

{

db = DatabaseFactory.CreateDatabase();

}

else

{

db = DatabaseFactory.CreateDatabase(dbConfigName);

}

return db;

}

而每个DAL层都会继承自AbstractBaseDAL,这样也就可以通过在DAL层指定dbConfigName进行使用不同的数据库的了。

但是这样问题出现了,假如我们有5个不同类型(SqlServer、Oracle、Mysql、Access、Sqlite)的数据库的DAL层,那么每个DAL层的实现类都要写一些代码,这样挺不方便,那么是否可以把它抽象到BLL层,这样只写一次配置就可以了,这个思路很好,我们具体来看看如何实现。

1)在IBaseDAL层定义接口

///

/// 数据访问层的接口

///

publicinterface IBaseDAL where T : BaseEntity

{

///

/// 设置数据库配置项名称

///

///

数据库配置项名称

void SetDbConfigName(string dbConfigName);

.............

}

2、在AbstractBaseDAL添加默认实现代码

///

/// 数据访问层的超级基类,所有数据库的数据访问基类都继承自这个超级基类,包括Oracle、SqlServer、Sqlite、MySql、Access等

///

publicabstractclass AbstractBaseDAL where T : BaseEntity, new()

{

///

/// 设置数据库配置项名称

///

///

数据库配置项名称

publicvirtualvoid SetDbConfigName(string dbConfigName)

{

this.dbConfigName = dbConfigName;

}

....................

}

3、在BaseBLL里面的Init函数进行调用设置处理

///

/// 参数赋值后,初始化相关对象

///

///

BLL业务类的全名(子类必须实现),子类构造函数传入this.GetType().FullName

///

数据访问层程序集的清单文件的文件名,不包括其扩展名。设置为NULL或默认为Assembly.GetExecutingAssembly().GetName().Name

///

BLL命名空间的前缀(BLL.)

///

数据库配置项名称

protectedvoid Init(string bllFullName, string dalAssemblyName = null, string bllPrefix = "BLL.")

{

.............

baseDal.SetDbConfigName(dbConfigName); //设置数据库配置项名称

}

4、在具体BLL层的业务类进行初始化处理。

///

/// 政策法规公告动态

///

publicclass Information : BaseBLL

{

public Information() : base()

{

base.Init(this.GetType().FullName, System.Reflection.Assembly.GetExecutingAssembly().GetName().Name, "BLL.", "annotherConfig" );

}

这样设置后,我们具体调用的代码不变,但是指定业务的数据库访问已经使用了特定的配置项名称了,如果配置项不存在,那么还是会获取默认的配置项进行处理了。

通过这样的实现步骤,我们就能实现在一个业务系统里面,分拆不同的数据库,进行统一管理,而且又不会增加额外的调用难度,对于我们很多业务表,这种框架的处理方式 ,应该是不错的。

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn