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

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

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

 

例子的目的

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

 

实现过程

1、数据库的建立

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

1   use test;

2   create table Customer

3   (

4       id int identity(1,1) primary key,

5       cName nvarchar(50),

6       cPhone nvarchar(50)

7   )

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

2、建立项目和类库的准备工作

 

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

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

3、对IDAL类库的代码实现

 

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

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

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

 

//ICustomer.cs接口的代码

    public interface ICustomer

    {

        bool Insert(Customer customer);

        Customer Get(int id);

    }

 

4、Model层代码的实现

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

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

 

View Code
 1 Customer.cs的代码:

 2 namespace Model

 3 {

 4     public class Customer

 5     {

 6         private int _id;

 7 

 8         public int Id

 9         {

10             get { return _id; }

11             set { _id = value; }

12         }

13         private string _cName;

14 

15         public string CName

16         {

17             get { return _cName; }

18             set { _cName = value; }

19         }

20         private string _cPhone;

21 

22         public string CPhone

23         {

24             get { return _cPhone; }

25             set { _cPhone = value; }

26         }

27     }

28 }

 

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

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

SQLServerCustomer.cs的代码 如下:

View Code
 1 namespace SQLServerDAL

 2 {

 3     public class SQLServerCustomer : ICustomer

 4     {

 5 

 6         public bool Insert(Model.Customer customer)

 7         {

 8             using (SqlConnection conn = new SqlConnection("server=.;database=test;uid=sa;pwd=123456"))

 9             {

10                 conn.Open();

11                 using (SqlCommand cmd = conn.CreateCommand())

12                 {

13                     cmd.CommandText = "insert into Customer(cName,cPhone) values('" + customer.CName + "','" + customer.CPhone + "');";

14                     cmd.ExecuteNonQuery();

15                     return true;

16                 }

17             }

18         }

19 

20         public Model.Customer Get(int id)

21         {

22             using (SqlConnection conn = new SqlConnection("server=.;database=test;uid=sa;pwd=123456"))

23             {

24                 conn.Open();

25                 using (SqlCommand cmd = conn.CreateCommand())

26                 {

27                     cmd.CommandText = "select * from Customer where id=" + id;

28                     SqlDataReader dr = cmd.ExecuteReader();

29 

30                     DataTable dt = new DataTable();

31                     dt.Load(dr);

32 

33                     Customer customer = new Customer();

34                     foreach (DataRow row in dt.Rows)

35                     {

36                         customer.CName = dt.Rows[0]["cName"].ToString();

37                         customer.CPhone = dt.Rows[0]["cPhone"].ToString();

38                         customer.Id = id;

39                     }

40                     return customer;

41                 }

42             }   

43         }

44     }

45 }

 

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);

        }

  

 

 

你可能感兴趣的:(设计模式)