快速业务通道

换一种思维实现数据库切换

作者 佚名技术 来源 NET编程 浏览 发布时间 2012-05-20

前言

当我们提到设计数据库无缝切换的时候,经常用到的办法就是用反射,连微软自带的例子Microsoft .NET Pet Shop也是如此。虽然如此,但一方面反射性能比较低,另一方面我觉得通过字符串的方式来切 换数据库难免不合适。近两天有想到用标准+冗余的办法来实现同样的需求,目前处于理论阶段,正在实 践中,现分享出来大家一起讨论下:)

正文

一、理论:

这里例举OracleDAL和SqlServerDAL。

将OracleDAL的dll名称设置为DAL.OracleDAL.dll,将SqlServerDAL名称设置为DAL.SqlServerDAL.dll ,但是两者内部的类名、方法名以及命名空气名称完全一样。也就是说,比如class:OracleDAL有一个 Insert方法,那么就将他的类名称改成DAL,Insert名称不变(如果标示了如OracleInsert,最好改成与数 据库不相关的名称);而class:SqlServerDAL也同样将类名改成DAL,外部方法需要和OracleDAL一直。这 样一来,我们同时引用两个dll会报错,我们只能引用一个dll,也就是我们切换数据库的时候只用替换一 下dll就可以了,不必用反射来了,由此大家也能看到冗余。但是仍然可以优化,理想的情况下,可以抽 出一个中间的dll(DAL.dll)来封装两者相同的代码以及标准接口,而DAL.OracleDAL.dll和 DAL.SqlServerDAL.dll都依赖并遵循于DAL.dll,这样能规范约束并且减少冗余。

二、实施:

通过反射达到无缝切换:更改数据库连接字符串+更改表示当前数据库的配置文件(一般都是如此做法) 。

通过标准+冗余到无缝切换:更改数据库连接字符串+更换dll。

三、简单示例:

1.DAL.Oracle.dll

1.1 OracleDAL.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Data.OracleClient;

using Model;

namespace Data
{
    //public class OracleDAL
    public class DAL
    {
        public void Insert(IModel model)
        {
            OracleCommand cmd = new OracleCommand("connectionstring");
            cmd.CommandText = "Insert into test(column1,column2) values (@column1,@column2)";
            //cmd.Parameters
            cmd.ExecuteNonQuery();
        }
    }
}

2. DAL.SqlServer.dll

2.1 SqlServerDAL.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Data.SqlClient;

using Model;

namespace Data
{
    //public class SqlServerDAL
    public class DAL
    {
        public void Insert(IModel model)
        {
            SqlCommand cmd = new SqlCommand("connectionstring");
            cmd.CommandText = "Insert into test(column1,column2) values (@column1,@column2)";
            //cmd.Parameters
            cmd.ExecuteNonQuery();
        }
    }
}

3.业务层/客户端调用代码

using Data;

    public class Program
    {
        static void Main(string[] args)
        {
            IModel model = new Model();
            new DAL().Insert(model);
        }
    }

4. 代码说明和分析

3.1 代码不能直接执行,主要是为了表达本文的意图,希望你理解后自己再写具体的代码试试看。

3.2 需要注意的是1和2分别是两个dll,类的文件名不同,但是类名和空间名称是一样的,所以项目 中只能存在一个。

3.3 需要注意的是,Insert在两个dll里面方面名称、类名、命名空间是一样的,但是方法内部实现 并不是一样的!!

3.4 如果我现在进行数据库切换,把DAL.SqlServer.dll和DAL.Oracle.dll两个之间任意的替换掉业 务层调用方是不用更改任何代码的!!因为类名、命名空间、方法都没有变!!

小结

由此可见,对于业务层,由于两者命名空间、类名、方法名一致,在更换dll的时候是无需改动代码的 ,并且性能也是要优于通过反射来实现数据库切换的,而且具有更强的可扩展性和随意性,可将现有的不 跨数据库的代码改改就可以下次复用了,在写其中任何一个针对数据库的dll的时候只要根据标准,就无 需考虑数据库兼容的问题了。

但是需要注意的是,在我们需要强类型(如SqlDataReader、SqlCommand)、直接执行SQL语句的时候就 需要和其他程序一样需要仔细设计了,比如对于SqlDataReader,不直接进行返回,或者给方法返回加一 个泛型支持,并约束泛型调用类必须也继承IDataReader接口,或者干脆直接返回一个Hashtable或 Dictionary;而SQL语句可以对应的建立一个SQL语句的工厂类,传一个结构体过来,然后根据结构体来生 成SQL语句,而不要直接写SQL语句来执行。

结束

目前我也在实践中,欢迎大家多多提意见和看法

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号