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


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

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

     

    例子的目的

      有时候项目里使用的是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);
            }
    

      

     

     

  • 相关阅读:
    进程和程序
    linux socket基本知识
    window核心编程 第五章 作业
    树的基本操作(C语言)
    每天都在反省自己,但是每天却都浑浑噩噩
    Windows核心编程 内核对象
    还没完整看过一本技术的书籍啊
    管道
    Memory Layout of a C Program(7.6)
    cpio命令用法
  • 原文地址:https://www.cnblogs.com/cxeye/p/2650622.html
Copyright © 2020-2023  润新知