设计模式- 使用抽象工厂实现多数据库切换实现过程

  目前我对设计模式方面了解的不多,会的设计模式五根手指头就能数完。怎么写好设计模式让读者看懂真的要讲究一下技巧,不能单纯的贴代码并对代码作解释,我觉的《大话设计模式》就是一本讲设计模式很好的书,那本书通过故事的形式讲解让人联想思考下去。

  由于水平有限,所有这篇文章没什么讲解的,只是写一下自己使用抽象工厂实现多数据库切换的实现过程。

 例子的目的

  有时候项目里使用的是ACCESS数据库,可是突然有一天想更改成MSSQLSERVER数据库,为了防止整站代码重写这种局面,可以使用抽象工厂+反射实现修改一下配置字符串就能实现ACCESS的MSSQLSERVER数据库的切换。

  实现过程

  1、数据库的建立

  为了例子的讲解的方便,我们就只在数据库里建立一张表,一张顾客表(Customer)。在MSSQLSERVER数据库里创建表的SQL语句如下:

  use test;
   create table Customer
   (
       id int identity(1,1) primary key,
       cName nvarchar(50),
       cPhone nvarchar(50)
   )

  在ACCESS数据库里也一样创建一张Customer表,字段名一样。

  2、建立项目和类库的准备工作
  先在VS里面建立一个空的WEB应用程序,我起名为抽象工厂DEMO,之后建立数据库的接口类库IDAL。再建立ACCESS的数据库访问类库为AccessDAL,SQLServer的数据库访问类库SQLServerDAL。AccessDAL和SQLServerDAL是对IDAL接口类库的实现,最后再建一个模型层Model。这样准备工作就好了。大概需要的类库和项目如下图所示:

  3、对IDAL类库的代码实现

  在IDAL就要建立一个类,可以在类里实现对表的增删查改等操作。这里为了做例子的方便就只实现增和查两个接口。

  建立一个类ICustomer,如下图所示

//ICustomer.cs接口的代码
    public interface ICustomer
    {
        bool Insert(Customer customer);
        Customer Get(int id);
    }

  4、对Model层代码的实现

  接口两个类,Customer.cs 如图:

 namespace Model
 {
     public class Customer
     {
         private int _id;
 
         public int Id
         {
             get { return _id; }
             set { _id = value; }
         }
         private string _cName;
 
         public string CName
         {
             get { return _cName; }
             set { _cName = value; }
         }
         private string _cPhone;
 
         public string CPhone
         {
             get { return _cPhone; }
             set { _cPhone = value; }
         }
     }
 }

  5、对SQLServerDAL类库里的代码的实现

  在SQLServerDAL里建立一个类SQLServerCustomer.cs。实现对ICustomer的接口。如图:

  SQLServerCustomer.cs的代码 如下:

 namespace SQLServerDAL
 {
     public class SQLServerCustomer : ICustomer
     {
 
         public bool Insert(Model.Customer customer)
         {
             using (SqlConnection conn = new SqlConnection("server=.;database=test;uid=sa;pwd=123456"))
             {
                 conn.Open();
                 using (SqlCommand cmd = conn.CreateCommand())
                 {
                     cmd.CommandText = "insert into Customer(cName,cPhone) values('" + customer.CName + "','" + customer.CPhone + "');";
                     cmd.ExecuteNonQuery();
                     return true;
                 }
             }
         }
 
         public Model.Customer Get(int id)
         {
             using (SqlConnection conn = new SqlConnection("server=.;database=test;uid=sa;pwd=123456"))
             {
                 conn.Open();
                 using (SqlCommand cmd = conn.CreateCommand())
                 {
                     cmd.CommandText = "select * from Customer where id=" + id;
                     SqlDataReader dr = cmd.ExecuteReader();
 
                     DataTable dt = new DataTable();
                     dt.Load(dr);
 
                     Customer customer = new Customer();
                     foreach (DataRow row in dt.Rows)
                     {
                         customer.CName = dt.Rows[0]["cName"].ToString();
                         customer.CPhone = dt.Rows[0]["cPhone"].ToString();
                         customer.Id = id;
                     }
                     return customer;
                 }
             }   
         }
     }
 }

 

  6、对AccessDAL类库里的代码实现

  这里在做的时候碰到一点问题,ACCESS数据库我放在WEB项目的DataBase文件夹里,可是在类库里如何WEB项目里的DataBase文件夹的数据库文件进行访问呢?

  必须要用到HttpContext.Current.Server.MapPath,在使用这句必需先引用using System.Web;

  AccessCustomer.cs的代码如下:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Web; 
using IDAL; 
  
using System.Data; 
using System.Data.OleDb; 
using Model; 
namespace AccessDAL 
{ 
    public class AccessCustomer:ICustomer 
    { 
  
        public static string connectionString = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + HttpContext.Current.Server.MapPath("/database/db1.mdb"); 
  
  
  
        public bool Insert(Model.Customer customer) 
        { 
            using (OleDbConnection conn = new OleDbConnection(connectionString)) 
            { 
                conn.Open(); 
                using (OleDbCommand cmd = conn.CreateCommand()) 
                { 
                    cmd.CommandText = "insert into Customer(cName,cPhone) values('" + customer.CName + "','" + customer.CPhone + "');"; 
                    cmd.ExecuteNonQuery(); 
                    return true; 
                } 
            } 
        } 
  
        public Model.Customer Get(int id) 
        { 
            using (OleDbConnection conn = new OleDbConnection(connectionString)) 
            { 
                conn.Open(); 
                using (OleDbCommand cmd = conn.CreateCommand()) 
                { 
                    cmd.CommandText = "select * from Customer where id=" + id; 
                    OleDbDataReader dr = cmd.ExecuteReader(); 
  
                    DataTable dt = new DataTable(); 
                    dt.Load(dr); 
  
                    Customer customer = new Customer(); 
                    foreach (DataRow row in dt.Rows) 
                    { 
                        customer.CName = dt.Rows[0]["cName"].ToString(); 
                        customer.CPhone = dt.Rows[0]["cPhone"].ToString(); 
                        customer.Id = id; 
                    } 
                    return customer; 
                } 
  
            } 
        } 
    } 
} 

  7、使用反射的DataAccess类实现数据库更改设计

  这里是关键,通过反射

  可以实现只要更改

    private static readonly string AssemblyName = "AccessDAL";
        private static readonly string db = "Access";

  就能实现对数据库更改的作用。

  上面是使用ACCESS数据库,如何我突然想更换成MSSQLSERVER数据库,那么我只要把这两句更改成

       private static readonly string AssemblyName = "SQLServerDAL";
       private static readonly string db = "SQLServer";

  就可以了。

 

  先在WEB项目里建一个类名为DataAccess。如图所示:

DataAccess的代码如下:

namespace 抽象工厂DEMO 
{ 
    public class DataAccess 
    { 
        //只需要更改这两处就行了 
        //private static readonly string AssemblyName = "SQLServerDAL"; 
        //private static readonly string db = "SQLServer"; 
  
        private static readonly string AssemblyName = "AccessDAL"; 
        private static readonly string db = "Access"; 
  
        public static ICustomer CreateCustomer() 
        { 
            string className = AssemblyName + "." + db + "Customer"; 
            return (ICustomer)Assembly.Load(AssemblyName).CreateInstance(className); 
        } 
    } 
} 

  完成这七部就可以了,建一个DEMO.ASPX页面做一下测试,代码如下

protected void Button1_Click(object sender, EventArgs e) 
{ 
    Customer customer = new Customer(); 
    customer.CName = "demo1"; 
    customer.CPhone = "9999"; 
    ICustomer ic = DataAccess.CreateCustomer(); 
    ic.Insert(customer); 
 
    Response.Write("success"); 
 
} 
 
protected void Button2_Click(object sender, EventArgs e) 
{ 
    Customer customer = new Customer(); 
    ICustomer ic = DataAccess.CreateCustomer(); 
    customer = ic.Get(1); 
    Response.Write(customer.CName); 
} 



 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值