工厂模式连接数据库

本文涉及的产品
云数据库 RDS SQL Server,独享型 2核4GB
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介:

在项目中通常可能会使用不同的数据源,可能是SQL Server也可能是ACCESS或者是Oracle,那么如何保证在使用不同数据源的时候,使项目代码更改的代价最小呢?
对,使用工厂模式.在Net1.1的时候,这需要项目实施者自己来完成.在Net2.0中,MS已经新增了几个用于实施工厂模式的类库.
首先我现在应用程序当前目录下新建Databases目录,再新建一个Access数据库与Sqlserver数据库
其中这2个数据库的结构都是一样的,都包含一个SampleData表,有ID,与IntegerValue字段

然后回到VS中新建一个WinForm工厂模式连接数据库 项目,然后编辑App.Config文件如下:

xml version="1.0" encoding="utf-8" ?>

<configuration>
    <connectionStrings>
    
        <add name="SQL Server" providerName="System.Data.SqlClient"        
          connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Databases\MyData.mdf;Integrated Security=True;User Instance=True" />
        <add name="MS Access" providerName="System.Data.OleDb" 
          connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\Databases\MyData.mdb;Persist Security Info=True" />    
    connectionStrings>

configuration>

然后在主窗体中的Button事件中编写如下代码

private void getDataButton_Click(object sender, EventArgs e)
        {
            try
            {
                //创建一个新的StopWatch来监视连接性能[Net2.0新增]
                Stopwatch myWatch = new Stopwatch();

                // 开始计算connection and retrieval of data所花费的时间
                myWatch.Start();

                // 选择要使用的数据源
                string strDataSource="MS Access";

                // 根据选者的数据源获得连接字符串的配置对象                
                ConnectionStringSettings objConnectionSettings = ConfigurationManager.ConnectionStrings[strDataSource];

                // 通过配置文件创建数据库驱动工厂的实例
                DbProviderFactory objProviderFactory = DbProviderFactories.GetFactory(objConnectionSettings.ProviderName);

                // 通过数据库驱动工厂创建DBConnection实例
                using (DbConnection objConnection = objProviderFactory.CreateConnection())
                {
                
                // 从 objConnectionSettings 中获取连接字符串
                objConnection.ConnectionString = objConnectionSettings.ConnectionString;

                // 打开 connection
                objConnection.Open();

                // 通过数据驱动工厂创建 数据适配器和 Command
                DbDataAdapter myAdapter = objProviderFactory.CreateDataAdapter();
                DbCommand myCommand = objProviderFactory.CreateCommand();
                
            
                string myQuery = "SELECT * FROM SampleData";
                DataSet myDataSet = new DataSet();

                myCommand.Connection = objConnection;
                myCommand.CommandText = myQuery;

                myAdapter.SelectCommand = myCommand;

                myAdapter.Fill(myDataSet);
                
                displayDataGridView.DataSource = myDataSet.Tables[0];

                // 停止StopWatch来查看连接和返回数据所花费的时间
                myWatch.Stop();
                elapsedTimeTextLabel.Text = "消耗时间: " +  myWatch.ElapsedMilliseconds.ToString() + " ms";
                providerLabel.Text = "数据驱动: " + objConnectionSettings.ProviderName.ToString();
                connectionStringLabel.Text = objConnectionSettings.ConnectionString.ToString();
            }
            }
            catch 
            {
                MessageBox.Show("出现错误.", "Alert");
            }
            
        }
    }

这样,只需要更改strDataSource就可以使用不同的数据源,而且整个项目都不需要为不同的数据库而烦恼
=====================================================================================================

使用设计模式构建通用数据库访问类

在应用程序的设计中,数据库的访问是非常重要的,我们通常需要将对数据库的访问集中起来,以保证良好的封装性和可维护性。在.Net中,数据库的访问,对于微软自家的SqlServer和其他数据库(支持OleDb),采用不同的访问方法,这些类分别分布于System.Data.SqlClient和System.Data.OleDb名称空间中。微软后来又推出了专门用于访问Oracle数据库的类库。我们希望在编写应用系统的时候,不因这么多类的不同而受到影响,能够尽量做到数据库无关,当后台数据库发生变更的时候,不需要更改客户端的代码。

这就需要我们在实际开发过程中将这些数据库访问类再作一次封装。经过这样的封装,不仅可以达到上述的目标,还可以减少操作数据库的步骤,减少代码编写量。在这个方面,微软为我们提供了Application Block,但是,可惜的是目前只支持Sql Server。这里,介绍一种在实际应用中得到了非常好的效果的实作策略——笔者编写的Websharp框架中的数据访问结构。Factory设计模式是使用的主要方法。

我们先来看看Factory的含义:定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。我们这里可能会处理对多种数据库的操作,因此,需要首先定义一个操纵数据库的接口,然后,根据数据库的不同,由类工厂决定实例化哪个类。

下面,我们首先来定义这个访问接口。为了方便说明问题,我们在这里只列出了比较少的方法,其他的方法是很容易参照添加的。

     public interface DataAccess

     {

         DatabaseType DatabaseType{get;}                  //数据库类型

          IDbConnection DbConnection{get;} //得到数据库连接

         void Open();                    //打开数据库连接

         void Close();                   //关闭数据库连接

         IDbTransaction BeginTransaction();              //开始一个事务

         int ExecuteNonQuery(string commandText);       //执行Sql语句

         DataSet ExecuteDataset(string commandText);//执行Sql,返回DataSet

}

 

因为,DataAccess的具体实现类有一些共同的方法,所以,先从DataAccess实现一个抽象的AbstractDataAccess类,包含一些公用方法。然后,我们分别为Sql Server、Oracle和OleDb数据库编写三个数据访问的具体实现类:

     public sealed class MSSqlDataAccess : AbstractDataAccess

     {

         ……//具体实现代码。

     }

 

     public class OleDbDataAccess : AbstractDataAccess

     {

          ……//具体实现代码。

     }

 

     public class OracleDataAccess : AbstractDataAccess

     {

         ……//具体实现代码。

     }

 

现在我们已经完成了所要的功能,下面,我们需要创建一个Factory类,来实现自动数据库切换的管理。这个类很简单,主要的功能就是根据数据库类型,返回适当的数据库操纵类。

     public sealed class DataAccessFactory

     {

         private DataAccessFactory(){}

         private static PersistenceProperty defaultPersistenceProperty;

         public static PersistenceProperty DefaultPersistenceProperty

         {

              get{return defaultPersistenceProperty;}

              set{defaultPersistenceProperty=value;}

         }

         public static DataAccess CreateDataAccess(PersistenceProperty pp)

         {

              DataAccess dataAccess;

              switch(pp.DatabaseType)

              {

                   case(DatabaseType.MSSQLServer):

                       dataAccess = new MSSqlDataAccess(pp.ConnectionString);

                       break;

                   case(DatabaseType.Oracle):

                       dataAccess = new OracleDataAccess(pp.ConnectionString);

                       break;

                   case(DatabaseType.OleDBSupported):

                       dataAccess = new OleDbDataAccess(pp.ConnectionString);

                       break;

                   default:

                       dataAccess=new MSSqlDataAccess(pp.ConnectionString);

                       break;

              }

              return dataAccess;

         }

         public static DataAccess CreateDataAccess()

         {

              return CreateDataAccess(defaultPersistenceProperty);

         }

     }

 

好了,现在,一切都完成了,客户端在代码调用的时候,可能就是采用如下形式:

PersistenceProperty pp = new PersistenceProperty();

pp.ConnectionString = "server=127.0.0.1;uid=sa;pwd=;database=Northwind;";

pp.DatabaseType = DatabaseType. MSSQLServer;

pp.UserID = “sa”;

pp.Password = “”;

DataAccess db= DataAccessFactory.CreateDataAccess(pp)

db.Open();

……//db.需要的操作

db.Close();

 

或者,如果事先设定了DataAccessFactory的DefaultPersistenceProperty属性,可以直接使用

DataAccess db= DataAccessFactory.CreateDataAccess()

方法创建DataAccess实例。

 

当数据库发生变化的时候,只需要修改PersistenceProperty的值,客户端不会感觉到变化,也不用去关心。这样,实现了良好的封装性。当然,前提是,你在编写程序的时候,没有用到特定数据库的特性,例如,Sql Server的专用函数。
=================================================================================

数据库访问一般有不同中数据库,比如Oracle,Sqlserver,Mysql等。 怎样使得程序有一定的通用性。我们可以使用工厂模式来实现。具体代码如下:

1 抽象类

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace HHSCInfor.App_Code.Database
...{
    /**//// <summary>
    /// Summary description for absDB
    /// </summary>
    public abstract class AbsDB
    ...{

        public AbsDB()
        ...{
            //
            // TODO: Add constructor logic here
            //
        }

        //得到数据库连接
        public abstract IDbConnection Connection ...{ get;}

        //打开数据库连接
        public abstract void Open();

        //关闭数据库连接
        public abstract void Close();

        //开始一个事务
        public abstract void BeginTrans();

        //提交一个事务
        public abstract void CommitTrans();

        //回滚一个事务
        public abstract void RollbackTrans();

        //执行Sql语句,没有返回值
        public abstract void ExeSql(string strSql, string[] strParams, object[] objValues);

        //执行Sql,返回DataSet
        public abstract DataSet ExeSqlForDataSet(string QueryString);

    }

}

2 Oracle连接的实例化

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using System.Data.OracleClient;

namespace HHSCInfor.App_Code.Database
...{
    /**//// <summary>
    /// Summary description for OracleDB
    /// </summary>
    internal class OracleDB : AbsDB
    ...{
        /**//// <summary>
        /// 数据库连接状态表示
        /// </summary>
        private string OpenFlag = "OPEN";

        public OracleDB()
        ...{

        }

        //数据库连接
        private OracleConnection conn;

        //事务处理类
        private OracleTransaction trans;

        //指示当前是否正处于事务中
        private bool inTransactionFlag = false;

        public override IDbConnection Connection
        ...{
            get ...{ return this.conn; }
        }

        public OracleDB(string strConnection)
        ...{
            this.conn = new OracleConnection(strConnection);
        }

        public override void Open()
        ...{
            if (conn.State.ToString().ToUpper() != OpenFlag)
                this.conn.Open();
        }

        public override void Close()
        ...{
            if (conn.State.ToString().ToUpper() == OpenFlag)
                this.conn.Close();
        }

        public override void BeginTrans()
        ...{
            trans = conn.BeginTransaction();
            inTransactionFlag = true;
        }

        public override void CommitTrans()
        ...{
            trans.Commit();
            inTransactionFlag = false;
        }

        public override void RollbackTrans()
        ...{
            trans.Rollback();
            inTransactionFlag = false;
        }


        public override void ExeSql(string strSql, string[] strParams, object[] strValues)
        ...{
            //创建命令
            OracleCommand cmd = new OracleCommand();

            //设置连接
            cmd.Connection=this.conn ;

            //比较参数个数和参数值数组的长度是否匹配
            if ((strParams != null) && (strParams.Length != strValues.Length))
            ...{
                throw new Exception("查询参数和值不对应!");
            } 

            cmd.CommandText = strSql;

            if (strParams != null)
            ...{
                for (int i = 0; i < strParams.Length; i++)
                ...{
                    cmd.Parameters.Add(strParams[i], strValues[i]);
                }
            }
            
            //执行SQL语句
            cmd.ExecuteNonQuery();
             
        }

        /**//// <summary>
        /// 执行数据库查询并将结果用数据集(DataSet)的形式返回
        /// </summary>
        /// <param name="QueryString">SQL语句</param>
        /// <returns></returns>
        public override DataSet ExeSqlForDataSet(string QueryString)
        ...{
            //创建命令
            OracleCommand cmd = new OracleCommand();

            //设置连接
            cmd.Connection = this.conn;

            //传入查询语句
            cmd.CommandText = QueryString;

            //创建数据集
            DataSet ds = new DataSet();
            
            //创建适配器
            OracleDataAdapter ad = new OracleDataAdapter();
            
            //适配器命令
            ad.SelectCommand = cmd;

            //填充到数据集(DataSet)
            ad.Fill(ds);

            //返回结果数据集
            return ds;
        }

    }

}

 

3 SqlServer的实例化(自己对照上面写个,我也没写。^_^)

4 根据不同的string连接来创建不同的实例。

web.config中设置共用连接:

  <appSettings>
    <add key="DBConnStr" value="Data Source=INFOPLAT;User ID=InfoManager;Password=admin;" />
  </appSettings>

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using System.Data.OracleClient;

namespace HHSCInfor.App_Code.Database
...{
    /**//// <summary>
    /// Summary description for DBConn
    /// </summary>
    public class DBConn
    ...{
        public DBConn()
        ...{

        }

        /**//// <summary>
        /// 根据不同的字符串连接来使用不同的处理程序。
        /// 工厂方法应用(可以根据不同的strConnection创建不同的连接)。
        /// </summary>
        /// <param name="strConnection">数据库连接字符串</param>
        /// <returns></returns>
        public static AbsDB GetDBConn()
        ...{
            // 只有一个Oracle连接时使用,如果有多个,在此添加。在Web.Config里配置。
            string strConnection = System.Configuration.ConfigurationManager.AppSettings["DBConnStr"];

            // 创建OracleDB连接对象
            return new OracleDB(strConnection);

            /**////比如有sqlserver添加如下
            ///if(strConnection=?)
            ///{
            ///     return(SqlServerDB(strConnection));
            ///}

        }

    }
}

5 测试程序:

        AbsDB conn = DBConn.GetDBConn();

        DataSet ds = conn.ExeSqlForDataSet("select * from sysFunction");

        this.Label1.Text = ds.Tables[0].Rows[2]["功能名称"].ToString();

        conn.Close();
        

我的测试通过。

 如果是连接池用单例来实现。
=========================================================================
 

作者:陈刚,桂林人,97年毕业于广西师范大学数学系,暂于IBM中国研究中心兼职从事软件开发(2004.2-?),专注基于java平台的软件开发。
email:   glchengang@hotmail.com 
blog:  glchengang.yeah.net
 
      随着模式概念的普及,了解模式和使用模式的程序员越来越多,很多人在学习模式的时候,都会有这样一种疑惑:“有必要搞得这么复杂吗?”。的确,因为教程的例子过于简单化(这样方便读者学习),或者是作者选例子的时候并没有很好体现所讲模式的优点,很多情况下如果仅就其例子的问题来说,用模式是太复杂了。因此才导致这样的误解:“模式就是把简单的问题复杂化吗?”。当然不是,随着你开发实践的不断丰富,你终会发现模式强大威力,而且模式也并非贵族化的编程方式,它就是一些经过提炼了的解决问题的方法技巧。
 
      通过学习模式,程序员开始告别过去准直线式的代码方式,模式开扩了我们的视野,强化了我们面向对象编程的思维方式。然而现在又出现了另一个普遍的问题,盲目应用模式。模式是问题的解决方案,先有问题才有模式,模式是依附于所要解决的问题的而生的。必须了解模式在很多情况下是以提高代码的复杂度为代价来增强灵活性、可复用性。如果在自已的代码中使用某一模式仅只提高了代码的复杂度,而其它方面收效甚微,或者某部份代码根本就不存在灵活性及高复用性的需求,那么我们就没有必要为使用模式而放弃更直观简单的代码写法。
 
      一流的高手90%精力关注问题的解决方案,因为找到了好的解决方案,再写起代码会很轻松代码也简洁流畅,看这样的代码是一种享受和提高;二流的熟手90%精力关注代码实现,因为问题的解决方案并非最佳,实现的代码也会比较复杂;三流菜鸟记流水帐,90%精力在敲键盘,常常做了大半才发现行不通,回过头来再用90%的时间敲键盘,根本不会用到任何模式,写出来的代码的只有他自已才能看懂。做出来的软件也是支离破碎,做一丁点改动都要大费周折,而且你还不知道改动后会产生什么问题,大有住危房里的感觉。
 
      在这里还是举一个滥用模式的例子吧。我曾参与过一个大集团公司OA系统的第二期开发,开发沿用原有代码架构并增加新的功能模块。文档很少我读原代码时就被它程序里的代码转来转去搞得头大如斗,最后读懂了:原代码架构总体采用工厂模式,而且是最复杂的抽象工厂模式。它把所有模块类都通过工厂生成还工厂套工厂,并且每一个模块类都有一个接口,每个接口也只有一个模块现实类,因为涉及权限控制还用了代理(proxy)模式。 读懂代码后我开始嵌入代码,发现每新增一个类,都要到六个Java文件中去增加相应代码,而在类中每增加一个方法,也要到它的接口等四个Java文件中去增加相应代码。天呀!!!记得当时我的小姆指常会不听使唤,就是因为频繁的使用Ctrl+C 、Ctrl+V,小姆指按着Ctrl键给累的。整个项目组苦不堪言,真烦透了。项目结束后我回顾发现:代理模式用得还对(现在针对权限这类横向控制有AOP编程这种新的解决办法了)但工厂模式在这里根本就是画蛇添足,不仅没有解决什么问题,反而增加代码复杂度和耦合性,降低了开发效率连维护难度都提高了。而且那种每个类简单的加一个接口的方式,更是没有道理,这让我很想说周星驰说过的一句话:“球~~~不是这么踢~~~~的,接口~~~不是这么用~~~的”。言归正传,我们先来看这样一个常见问题:某系统需要支持多种类型的数据库。用过Oracle、MSSQL等数据库的人都知道,它们的SQL编写方式都各有些不同。比如说Oracle的唯一标识自动+1字段用的是序列,MSSQL改一下字段属性就成了,还有各种各自特有的SQL用法。为了支持多数据库,难道我们要开发多套系统?当然NO。请看下面的解决方案。
 
      即然数据库存在多种,我们可以将系统中所有对数据库的操作抽象出来,写成一个个方法组合到一个类中,有几种数据库我们就写几个这样的类。具体设计类图如下:
 
 
简要说明:
  • OracleDataOperate、SqlserverDataOperate、MysqlDataOperate,分别代表Oracle、Sqlserver、Mysql这三种数据库的操作类。继承自AbstractDataOperate
  • AbstractDataOperate是一个抽象类,包含了那些不同种类数据库都是一样代码的操作方法。继承自DataOperate
  • DataOperate是上面说的数据操作类的统一接口,只有两个方法:取得一条记录、插入一条记录。
  • DataOperateFactory是一个工厂方法,统一用它的方法来得到数据库操作类的实例。
  • SampleClass是我们系统的某个功能模块的类。
  • People是一个实体类,代表一条记录。三个字段 oid唯一标识符、name姓名、date生日。
 
详细说明:
1、所有系统功能模块类只认DataOperat这个接口还不必管具体的实现类是OracleDataOperate还SqlserverDataOperate。DataOperate源代码如下:
public interface DataOperate {
    //根据记录的唯一标识取出一条记录
    People getPeople(String oid);
    //插入一条记录
    boolean insertPeople(People people);
}
 
2、AbstractDataOperate、OracleDataOperate、SqlserverDataOperate、MysqlDataOperate都是继承DataOperate接口的,没什么好说的,省略。
 
3、DataOperateFactory。我们看看工厂方法怎么写的。
public class DataOperateFactory {
    public static final int ORACLE = 0; //定义三个表示数据库类型的常量
    public static final int MYSQL = 1;
    public static final int SQLSERVER = 2;
 
    private static DataOperate db;
    private static int dataType = MYSQL;
    /**
     * 根据数据库类型(dataType)取得一个数据库操作类的实例,
     * 这里对DataOperate使用了单例模式,因为OracelDataOperate等都是无状态的工具类,
     * 所以整个系统只保留一个实例就行了。
     *
     * @return 返回的是接口,客户端不必关心具体是用那个实现类
     */
    public static DataOperate getInstance() {
        if (db == null) {
            if (dataType == ORACLE) //根据dateType返回相应的实现类
                return new OracelDataOperate();
            if (dataType == MYSQL)
                return new MysqlDataOperate();
            if (dataType == SQLSERVER)
                return new SqlserverDataOperate();
        }
        return db;
    }
}
 
4、接下来就看看使用端是如何调用工厂方法和使用数据操作类的。
/**
 * 系统某个功能类
 */
public class SampleClass {
private DataOperate db; //声明一个数据库操作类,注意这里用的是接口噢
    /**某方法*/
    public void sampleMethod() {
        db = DataOperateFactory.getInstance();//得到单一实例
        People p = db.getPeople("123"); //取得一条记录
        db.insertPeople(p);//再插回去
    }
}
 
  我们发现SampleClass中根本没有出现OracelDataOperate、MysqlDataOperate等的影子,这就是接口的威力。客户端不必针对OracelDataOperate等写不同的代码,它只关心DataOperate即可,具体要取那个类的逻辑就由DataOperateFactory负责了。
 
总结:
  • 从例子中我们可以看到什么是面向接口的编程方式。SampleClass使用数据操作类可以不必关心具体是那个类,只要是符合接口的都行
  • 要实例?只须调用DataOperateFactory.getInstance()即可,其它的交于DataOperateFactory这个工厂来做吧,使用端什么都不用关心。
  • 我们要支持新的数据库类型,只须要象OracelDataOperate那样,再写一个继承AbstractDataOperate的类即可,比如SysbaseDataOperate。然后到DataOperateFactory中加入相应代码即可。
  • 如果我们想要可配置性更高,可以用private static int dataType = MYSQL;中的值设置到一个文本文件中。
  对于开发支持多种数据库的系统,强烈建议使用hibernate,我现在做的系统就是用hibernate的,开发时用Mysql,到要给客户时将数据库换了DB2,程序不用做任何改动,真正的无逢移植。不过这样,本文所提到的方法就没什么用了.


作者Blog: http://blog.csdn.net/glchengang/
=====================================================================================
 简单工厂模式就是根据提供给它的数据,返回几个可能类中的一个类的实例.通常它返回的类都有一个共同的父类和共同的方法,但是每个方法执行的任务不同,而且根据不同的数据进行了优化。比如X是一个基类,xy和xz是从它派生出来的,XFactory类根据给出的参数决定返回那一个子类,返回那一个类的实例与程序员无关,因为这些类有同样的方法,只是实现不同,返回那个类的实例取决于工厂,工厂功能可能很复杂,但通常都是相当简间的.

 

    接下来我们用一个例子来说明这个简单的工厂模式.假如我们要输入一个人的姓名,

    有两个方式,一种是“firstname lastname” 和“fristname,lastname”形式.我们的任务就是要确定lastname和firstname是否是逗号来确定姓名的先后.

第一步,设计一个父类:

    public class CName 
    {
        protected  string frName ,lName;
        public string getFristName() { return frName;}
        
public string getLastName() { return lName;}
    }

第二步,设计两个子类,它是由类CName的派生的。它们现实了接口,并在构造function中将名字分成了两部分.在CFirstFirst类中,做了一个简单的假设:最后一个空格前面的所有部分都属与firstname.

    public class CFirstFirst : CName  
    {
        public CFirstFirst (string sName) 
        {
            int i = sName.Trim().Indexof(” “);
            if ( i >0 ) 
            { 
                frName  = name.Substring(0,i).Trim();
                
lName = name.Substring(i+1).Trim();
            
}
            
else  
            {
                lName = sName;
                frName = “”;
            }
        }
    }

     在LastFist类中,用逗号给lastname划分界限.当空格或逗号不存在时,两个类都提供了错误校正处理.

    public class LastFrist  :CName  
    {
        public LastFrist(string sName) 
        {
            int i = sName.Indexof(”,”);
            if ( i>0 ) 
            {
                if ( i >0 ) 
                { 
                    lName = name.Substring(0,i).Trim();
                    frName = name.Substring(i+1).Trim();
                }
                else  
                {
                    lName = sName;
                    frName = “”;
                }
            }
        }
    }

两种情况下,都把分开的名字保存在基类的CName中保护变量中.所以在派生类中根本不需要任何getFirstName和getLastName方法,因为基类中已给出.

第三步: 构造简单工厂.

     现在很容易给出简单工厂类.只检查逗号来决定返回那个类的实例

    public class NameFactory ()
    { 
        public CName  getName(string sname)   
        {
            int i = sname.Indexof(”,”);
            if ( i >0 )
            {
                return new LastFrist  (sname);
            }
            else
            {
                return new CFirstFirst (sname);
            }
        }
    }

第四步。使用工厂类:

    string sName = “cedy hao”;
    NameFactory  nf = new NameFactory ();
    CName  name = nf.getName(sName);
    string sFristName = name.getFristName();
    string sLastName = name.getLastName();

    这种方法把和数据相关的问题与类的其它的方法分隔开来。采用抽象工厂模式设计出的系统类图如下:


数据库层抽象工厂解决方案归档:


(1)AbstractDbFactory.cs

using System;
using System.Data;

namespace DbService
{
    /// <summary>
    /// 数据库抽象工厂接口
    /// </summary>

    public interface AbstractDbFactory
    {
        /// <summary>
        /// 建立默认连接
        /// </summary>
        /// <returns>数据库连接</returns>

        IDbConnection CreateConnection();

        /// <summary>
        /// 根据连接字符串建立Connection对象
        /// </summary>
        /// <param name="strConn">连接字符串</param>
        /// <returns>Connection对象</returns>

        IDbConnection CreateConnection(string strConn);

        /// <summary>
        /// 建立Command对象
        /// </summary>
        /// <returns>Command对象</returns>

        IDbCommand CreateCommand();

        /// <summary>
        /// 建立DataAdapter对象
        /// </summary>
        /// <returns>DataAdapter对象</returns>

        IDbDataAdapter CreateDataAdapter();

        /// <summary>
        /// 根据Connection建立Transaction
        /// </summary>
        /// <param name="myDbConnection">Connection对象</param>
        /// <returns>Transaction对象</returns>

        IDbTransaction CreateTransaction(IDbConnection myDbConnection);

        /// <summary>
        /// 根据Command建立DataReader
        /// </summary>
        /// <param name="myDbCommand">Command对象</param>
        /// <returns>DataReader对象</returns>

        IDataReader CreateDataReader(IDbCommand myDbCommand);

        /// <summary>
        /// 获得连接字符串
        /// </summary>
        /// <returns>连接字符串</returns>

        string GetConnectionString();
    }
}

(2)Factory.cs

using System;
using System.Configuration;

namespace DbService
{
    /// <summary>
    /// Factory类
    /// </summary>

    public sealed class Factory
    {
        private static volatile Factory singleFactory = null;
        private static object syncObj = new object();
        
        
/// <summary>
        /// Factory类构造函数
        /// </summary>

        private Factory()
        {
        }

        /// <summary>
        /// 获得Factory类的实例
        /// </summary>
        /// <returns>Factory类实例</returns>

        public static Factory GetInstance()
        {
            if(singleFactory == null)
            {
                lock(syncObj)
                {
                    if(singleFactory == null)
                    {
                        singleFactory = new Factory();
                    }
                }
            }
            return singleFactory;
        }

        /// <summary>
        /// 建立Factory类实例
        /// </summary>
        /// <returns>Factory类实例</returns>

        public AbstractDbFactory CreateInstance()
        {
            AbstractDbFactory abstractDbFactory = null;
            switch(ConfigurationSettings.AppSettings["DatabaseType"].ToLower())
            {
                case "sqlserver":
                {
                    abstractDbFactory = new SqlFactory();
                    break;
                }
                case "oledb":
                {
                    abstractDbFactory = new OleDbFactory();
                    break;
                }
                case "odbc":
                {
                    abstractDbFactory = new OdbcFactory();
                    break;
                }
            }   
            return abstractDbFactory;
        }
    }
}

     以下3个类分别是Factory针对SqlServer专用连接、OleDb连接和Odbc连接时的具体实现:

(3)SqlFactory.cs

using System;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

namespace DbService
{
    /// <summary>
    /// 针对SqlServer专用连接的工厂
    /// </summary>

    public class SqlFactory : AbstractDbFactory
    {
        /// <summary>
        /// 构造函数
        /// </summary>

        public SqlFactory()
        {
        }

        /// <summary>
        /// 建立默认Connection对象
        /// </summary>
        /// <returns>Connection对象</returns>
        public IDbConnection CreateConnection()
        {
            return new SqlConnection();
        }

        /// <summary>
        /// 根据连接字符串建立Connection对象
        /// </summary>
        /// <param name="strConn">连接字符串</param>
        /// <returns>Connection对象</returns>

        public IDbConnection CreateConnection(string strConn)
        {
            return new SqlConnection(strConn);
        }

        /// <summary>
        /// 建立Command对象
        /// </summary>
        /// <returns>Command对象</returns>

        public IDbCommand CreateCommand()
        {
            return new SqlCommand();
        }

        /// <summary>
        /// 建立DataAdapter对象
        /// </summary>
        /// <returns>DataAdapter对象</returns>

        public IDbDataAdapter CreateDataAdapter()
        {
            return new SqlDataAdapter();
        }

        /// <summary>
        /// 根据Connection建立Transaction
        /// </summary>
        /// <param name="myDbConnection">Connection对象</param>
        /// <returns>Transaction对象</returns>

        public IDbTransaction CreateTransaction(IDbConnection myDbConnection)
        {
            return myDbConnection.BeginTransaction();
        }

        /// <summary>
        /// 根据Command建立DataReader
        /// </summary>
        /// <param name="myDbCommand">Command对象</param>
        /// <returns>DataReader对象</returns>

        public IDataReader CreateDataReader(IDbCommand myDbCommand)
        {
            return myDbCommand.ExecuteReader();
        }

        /// <summary>
        /// 获得连接字符串
        /// </summary>
        /// <returns>连接字符串</returns>

        public string GetConnectionString()
        {
            string strServer = ConfigurationSettings.AppSettings["SqlServerServer"];
            string strDatabase = ConfigurationSettings.AppSettings["SqlServerDatabase"];
            string strUid = ConfigurationSettings.AppSettings["SqlServerUid"];
            string strPwd = ConfigurationSettings.AppSettings["SqlServerPwd"];
            string strConnectionString = "Server = " + strServer + "; Database = " + strDatabase + "; Uid = " + strUid + "; Pwd = " + strPwd + ";";
            return strConnectionString;
        }
    }
}

(4)OleDbFactory.cs

using System;
using System.Data;
using System.Data.OleDb;
using System.Configuration;

namespace DbService
{
    /// <summary>
    /// 针对OleDb连接的工厂
    /// </summary>

    public class OleDbFactory : AbstractDbFactory
    {
        /// <summary>
        /// 构造函数
        /// </summary>

        public OleDbFactory()
        {
        }

        /// <summary>
        /// 建立默认Connection对象
        /// </summary>
        /// <returns>Connection对象</returns>

        public IDbConnection CreateConnection()
        {
            return new OleDbConnection();
        }

        /// <summary>
        /// 根据连接字符串建立Connection对象
        /// </summary>
        /// <param name="strConn">连接字符串</param>
        /// <returns>Connection对象</returns>

        public IDbConnection CreateConnection(string strConn)
        {
            return new OleDbConnection(strConn);
        }

        /// <summary>
        /// 建立Command对象
        /// </summary>
        /// <returns>Command对象</returns>

        public IDbCommand CreateCommand()
        {
            return new OleDbCommand();
        }

        /// <summary>
        /// 建立DataAdapter对象
        /// </summary>
        /// <returns>DataAdapter对象</returns>

        public IDbDataAdapter CreateDataAdapter()
        {
            return new OleDbDataAdapter();
        }

        /// <summary>
        /// 根据Connection建立Transaction
        /// </summary>
        /// <param name="myDbConnection">Connection对象</param>
        /// <returns>Transaction对象</returns>

        public IDbTransaction CreateTransaction(IDbConnection myDbConnection)
        {
            return myDbConnection.BeginTransaction();   
        }

        /// <summary>
        /// 根据Command建立DataReader
        /// </summary>
        /// <param name="myDbCommand">Command对象</param>
        /// <returns>DataReader对象</returns>

        public IDataReader CreateDataReader(IDbCommand myDbCommand)
        {
            return myDbCommand.ExecuteReader();
        }

        /// <summary>
        /// 获得连接字符串
        /// </summary>
        /// <returns>连接字符串</returns>

        public string GetConnectionString()
        {
            string strProvider = ConfigurationSettings.AppSettings["OleDbProvider"];
            string strDataSource = ConfigurationSettings.AppSettings["OleDbDataSource"];
            string strConnectionString = "Provider = " + strProvider + ";Data Source = " + strDataSource + ";";
            return strConnectionString;
        }
    }
}

(5)OdbcFactory.cs

using System;
using System.Data;
using System.Data.Odbc;
using System.Configuration;

namespace DbService
{
    /// <summary>
    /// 针对Odbc连接的工厂
    /// </summary>

    public class OdbcFactory : AbstractDbFactory
    {
        /// <summary>
        /// 构造函数
        /// </summary>

        public OdbcFactory()
        {
        }

        /// <summary>
        /// 建立默认Connection对象
        /// </summary>
        /// <returns>Connection对象</returns>

        public IDbConnection CreateConnection()
        {
            return new OdbcConnection();
        }

        /// <summary>
        /// 根据连接字符串建立Connection对象
        /// </summary>
        /// <param name="strConn">连接字符串</param>
        /// <returns>Connection对象</returns>

        public IDbConnection CreateConnection(string strConn)
        {
            return new OdbcConnection(strConn);
        }

        /// <summary>
        /// 建立Command对象
        /// </summary>
        /// <returns>Command对象</returns>

        public IDbCommand CreateCommand()
        {
            return new OdbcCommand();
        }

        /// <summary>
        /// 建立DataAdapter对象
        /// </summary>
        /// <returns>DataAdapter对象</returns>

        public IDbDataAdapter CreateDataAdapter()
        {
            return new OdbcDataAdapter();
        }

        /// <summary>
        /// 根据Connection建立Transaction
        /// </summary>
        /// <param name="myDbConnection">Connection对象</param>
        /// <returns>Transaction对象</returns>

        public IDbTransaction CreateTransaction(IDbConnection myDbConnection)
        {
            return myDbConnection.BeginTransaction();
        }

        /// <summary>
        /// 根据Command建立DataReader
        /// </summary>
        /// <param name="myDbCommand">Command对象</param>
        /// <returns>DataReader对象</returns>

        public IDataReader CreateDataReader(IDbCommand myDbCommand)
        {
            return myDbCommand.ExecuteReader();
        }

        /// <summary>
        /// 获得连接字符串
        /// </summary>
        /// <returns></returns>

        public string GetConnectionString()
        {
            string strDriver = ConfigurationSettings.AppSettings["OdbcDriver"];
            string strDBQ = ConfigurationSettings.AppSettings["OdbcDBQ"];
            string strConnectionString = "Driver={" + strDriver + "}; DBQ=" + strDBQ + ";";
            return strConnectionString;   
        }
    }
}

 

用C#实现的数据库抽象工厂(三)

     以下是在应用时真正要调用到的类:

(6)DbAccess.cs

using System;
using System.Data;

namespace DbService
{
    /// <summary>
    /// DbAccess类,即进行数据库访问时需要调用的类
    /// </summary>

    public sealed class DbAccess
    {
        /// <summary>
        /// DbAccess构造函数
        /// </summary>

        private DbAccess()
        {
        }

        /// <summary>
        /// 无条件查询操作,即查询表中所有记录
        /// </summary>
        /// <param name="strTableName">表名</param>
        /// <param name="strColumn">列名组</param>
        /// <returns>无条件查询结果</returns>

        public static DataSet SelectAll(string strTableName, string[] strColumn)
        {
            DataSet ds = new DataSet();
            Factory factory = Factory.GetInstance();
            AbstractDbFactory abstractDbFactory = factory.CreateInstance();
            IDbConnection concreteDbConn = abstractDbFactory.CreateConnection();
            concreteDbConn.ConnectionString = abstractDbFactory.GetConnectionString();
            concreteDbConn.Open();
            IDbCommand concreteDbCommand = abstractDbFactory.CreateCommand();
            IDbTransaction concreteDbTrans = abstractDbFactory.CreateTransaction(concreteDbConn);
            concreteDbCommand.Connection = concreteDbConn;
            concreteDbCommand.Transaction = concreteDbTrans;
            IDbDataAdapter concreteDbAdapter = abstractDbFactory.CreateDataAdapter();
            try
            {
                string strSql = "Select ";
                for(int i = 0; i < strColumn.Length - 1; i++)
                {
                    strSql += (strColumn[i] + ", ");
                }
                strSql += (strColumn[strColumn.Length - 1] + " FROM " + strTableName);
                concreteDbCommand.CommandText = strSql;
                concreteDbAdapter.SelectCommand = concreteDbCommand;    
                concreteDbAdapter.Fill(ds);
                concreteDbTrans.Commit();
            }
            catch
            {
                concreteDbTrans.Rollback();
                ds.Clear();
                throw;
            }
            finally
            {
                concreteDbConn.Close();
            }  
            return ds;
        }

        /// <summary>
        /// 条件查询操作
        /// </summary>
        /// <param name="strTableName">表名</param>
        /// <param name="strColumn">列名组</param>
        /// <param name="strCondition">条件</param>
        /// <returns>条件查询结果</returns>

        public static DataSet Select(string strTableName, string[] strColumn, string strCondition)
        {
            DataSet ds = new DataSet();
            Factory factory = Factory.GetInstance();
            AbstractDbFactory abstractDbFactory = factory.CreateInstance();
            IDbConnection concreteDbConn = abstractDbFactory.CreateConnection();
            concreteDbConn.ConnectionString = abstractDbFactory.GetConnectionString();
            concreteDbConn.Open();
            IDbCommand concreteDbCommand = abstractDbFactory.CreateCommand();
            IDbTransaction concreteDbTrans = abstractDbFactory.CreateTransaction(concreteDbConn);
            concreteDbCommand.Connection = concreteDbConn;
            concreteDbCommand.Transaction = concreteDbTrans;
            IDbDataAdapter concreteDbAdapter = abstractDbFactory.CreateDataAdapter();
            try
            {
                string strSql = "Select ";
                for(int i = 0; i < strColumn.Length - 1; i++)
                {
                    strSql += (strColumn[i] + ", ");
                }
                strSql += (strColumn[strColumn.Length - 1] + " FROM " + strTableName + " Where " + strCondition);
                concreteDbCommand.CommandText = strSql;
                concreteDbAdapter.SelectCommand = concreteDbCommand;    
                concreteDbAdapter.Fill(ds);
                concreteDbTrans.Commit();
            }
            catch
            {
                concreteDbTrans.Rollback();
                ds.Clear();
                throw;
            }
            finally
            {
                concreteDbConn.Close();
            }
            return ds;
        }

        /// <summary>
        /// 单条记录的插入操作
        /// </summary>
        /// <param name="strTableName">表名</param>
        /// <param name="strColumn">列名组</param>
        /// <param name="strValue">值组</param>

        public static void Insert(string strTableName, string[] strColumn, object[] strValue)
        {
            Factory factory = Factory.GetInstance();
            AbstractDbFactory abstractDbFactory = factory.CreateInstance();
            IDbConnection concreteDbConn = abstractDbFactory.CreateConnection();
            concreteDbConn.ConnectionString = abstractDbFactory.GetConnectionString();   
            concreteDbConn.Open();
            IDbCommand concreteDbCommand = abstractDbFactory.CreateCommand();
            IDbTransaction concreteDbTrans = abstractDbFactory.CreateTransaction(concreteDbConn);
            concreteDbCommand.Connection = concreteDbConn;
            concreteDbCommand.Transaction = concreteDbTrans;
            try
            {
                string strSql = "Insert INTO " + strTableName + " (";
                for(int i = 0; i < strColumn.Length - 1; i++)
                {
                    strSql += (strColumn[i] + ", ");
                }
                strSql += (strColumn[strColumn.Length - 1] + ") VALUES ('");
                for(int i = 0; i < strValue.Length - 1; i++)
                {
                    strSql += (strValue[i] + "', '");
                }
                strSql += (strValue[strValue.Length - 1] + "')");
                concreteDbCommand.CommandText = strSql;
                concreteDbCommand.ExecuteNonQuery();
                concreteDbTrans.Commit();
            }
            catch
            {
                concreteDbTrans.Rollback();
                throw;
            }
            finally
            {
                concreteDbConn.Close();
            }   
        }

        /// <summary>
        /// 批量记录的插入操作,即可一次向多张表中插入不同的批量记录
        /// </summary>
        /// <param name="ds">批量记录组成的DataSet,DataSet中的各个DataTable名为表名,各DataTable中的DataColumn名为列名</param>

        public static void InsertSet(ref DataSet ds)
        {
            Factory factory = Factory.GetInstance();
            AbstractDbFactory abstractDbFactory = factory.CreateInstance();
            IDbConnection concreteDbConn = abstractDbFactory.CreateConnection();
            concreteDbConn.ConnectionString = abstractDbFactory.GetConnectionString();   
            concreteDbConn.Open();
            IDbCommand concreteDbCommand = abstractDbFactory.CreateCommand();
            IDbTransaction concreteDbTrans = abstractDbFactory.CreateTransaction(concreteDbConn);
            concreteDbCommand.Connection = concreteDbConn;
            concreteDbCommand.Transaction = concreteDbTrans;
            try
            {
                foreach(DataTable dt in ds.Tables)
                {
                    foreach(DataRow dr in dt.Rows)
                    {
                        string strSql = "Insert INTO " + dt.TableName + " (";
                        for(int i = 0; i < dt.Columns.Count - 1; i++)
                        {
                            strSql += (dt.Columns[i].Caption + ", ");
                        }
                        strSql += (dt.Columns[dt.Columns.Count - 1].Caption + ") VALUES ('");
                        for(int i = 0; i < dt.Columns.Count - 1; i++)
                        {
                            strSql += (dr[i] + "', '");
                        }
                        strSql += (dr[dt.Columns.Count - 1] + "')");
                        concreteDbCommand.CommandText = strSql;
                        concreteDbCommand.ExecuteNonQuery();
                    }
                }
                concreteDbTrans.Commit();
            }

            catch
            {
                concreteDbTrans.Rollback();
                throw;
            }

            finally
            {
                concreteDbConn.Close();
            }   
        }

        /// <summary>
        /// 无条件删除操作,即删除表中所有记录
        /// </summary>
        /// <param name="strTableName">表名</param>

        public static void DeleteAll(string strTableName)
        {
            Factory factory = Factory.GetInstance();
            AbstractDbFactory abstractDbFactory = factory.CreateInstance();
            IDbConnection concreteDbConn = abstractDbFactory.CreateConnection();
            concreteDbConn.ConnectionString = abstractDbFactory.GetConnectionString();
            concreteDbConn.Open();
            IDbCommand concreteDbCommand = abstractDbFactory.CreateCommand();
            IDbTransaction concreteDbTrans = abstractDbFactory.CreateTransaction(concreteDbConn);
            concreteDbCommand.Connection = concreteDbConn;
            concreteDbCommand.Transaction = concreteDbTrans;
            try
            {
                string strSql = "Delete FROM " + strTableName;
                concreteDbCommand.CommandText = strSql;
                concreteDbCommand.ExecuteNonQuery();
                concreteDbTrans.Commit();
            }
            catch
            {
                concreteDbTrans.Rollback();
                throw;
            }
            finally
            {
                concreteDbConn.Close();
            }   
        }

        /// <summary>
        /// 条件删除操作
        /// </summary>
        /// <param name="strTableName">表名</param>
        /// <param name="strCondition">条件</param>

        public static void Delete(string strTableName, string strCondition)
        {
            Factory factory = Factory.GetInstance();
            AbstractDbFactory abstractDbFactory = factory.CreateInstance();
            IDbConnection concreteDbConn = abstractDbFactory.CreateConnection();
            concreteDbConn.ConnectionString = abstractDbFactory.GetConnectionString();
            concreteDbConn.Open();
            IDbCommand concreteDbCommand = abstractDbFactory.CreateCommand();
            IDbTransaction concreteDbTrans = abstractDbFactory.CreateTransaction(concreteDbConn);
            concreteDbCommand.Connection = concreteDbConn;
            concreteDbCommand.Transaction = concreteDbTrans;
            try
            {
                string strSql = "Delete FROM " + strTableName + " Where " + strCondition;
                concreteDbCommand.CommandText = strSql;
                concreteDbCommand.ExecuteNonQuery();
                concreteDbTrans.Commit();
            }
            catch
            {
                concreteDbTrans.Rollback();
                throw;
            }
            finally
            {
                concreteDbConn.Close();
            }   
        }

        /// <summary>
        /// 无条件更新操作,即更新表中所有记录
        /// </summary>
        /// <param name="strTableName">表名</param>
        /// <param name="strColumn">列名组</param>
        /// <param name="strValue">值组</param>

        public static void UpdateAll(string strTableName, string[] strColumn, object[] strValue)
        {
            Factory factory = Factory.GetInstance();
            AbstractDbFactory abstractDbFactory = factory.CreateInstance();   
            IDbConnection concreteDbConn = abstractDbFactory.CreateConnection();
            concreteDbConn.ConnectionString = abstractDbFactory.GetConnectionString();
            concreteDbConn.Open();
            IDbCommand concreteDbCommand = abstractDbFactory.CreateCommand();
            IDbTransaction concreteDbTrans = abstractDbFactory.CreateTransaction(concreteDbConn);
            concreteDbCommand.Connection = concreteDbConn;
            concreteDbCommand.Transaction = concreteDbTrans;
            try
            {
                string strSql = "Update " + strTableName + " SET ";
                for(int i = 0; i < strColumn.Length - 1; i++)
                {
                    strSql += (strColumn[i] + " = '" + strValue[i] + "', ");
                }
                strSql += (strColumn[strColumn.Length - 1] + " = '" + strValue[strValue.Length - 1] + "' ");
                concreteDbCommand.CommandText = strSql;
                concreteDbCommand.ExecuteNonQuery();
                concreteDbTrans.Commit();
            }
            catch
            {
                concreteDbTrans.Rollback();
                throw;
            }
            finally
            {
                concreteDbConn.Close();
            }
        }

        /// <summary>
        /// 条件更新操作
        /// </summary>
        /// <param name="strTableName">表名</param>
        /// <param name="strColumn">列名组</param>
        /// <param name="strValue">值组</param>
        /// <param name="strCondition">条件</param>
        public static void Update(string strTableName, string[] strColumn, object[] strValue, string strCondition)
        {
            Factory factory = Factory.GetInstance();
            AbstractDbFactory abstractDbFactory = factory.CreateInstance();   
            IDbConnection concreteDbConn = abstractDbFactory.CreateConnection();
            concreteDbConn.ConnectionString = abstractDbFactory.GetConnectionString();
            concreteDbConn.Open();
            IDbCommand concreteDbCommand = abstractDbFactory.CreateCommand();
            IDbTransaction concreteDbTrans = abstractDbFactory.CreateTransaction(concreteDbConn);
            concreteDbCommand.Connection = concreteDbConn;
            concreteDbCommand.Transaction = concreteDbTrans;
            try
            {
                string strSql = "Update " + strTableName + " SET ";
                for(int i = 0; i < strColumn.Length - 1; i++)
                {
                    strSql += (strColumn[i] + " = '" + strValue[i] + "', ");
                }
                strSql += (strColumn[strColumn.Length - 1] + " = '" + strValue[strValue.Length - 1] + "' " + " Where " + strCondition);
                concreteDbCommand.CommandText = strSql;
                concreteDbCommand.ExecuteNonQuery();
                concreteDbTrans.Commit();
            }
            catch
            {
                concreteDbTrans.Rollback();
                throw;
            }
            finally
            {
                concreteDbConn.Close();
            }
        }
    }
}

最后一步,在Web.config中的根结点configuration下增加一些关于数据库连接字符串的变量:

<appSettings>
 
    <add key="DatabaseType" value="SqlServer" />
 
    <add key="SqlServerServer" value="flyingyoko" />
    <add key="SqlServerDatabase" value="test" />
    <add key="SqlServerUid" value="sa" />
    <add key="SqlServerPwd" value="****" />
 
    <add key="OleDbProvider" value="Microsoft.jet.oledb.4.0" />
    <add key="OleDbDataSource" value="D:\test.mdb" />
 
    <add key="OdbcDriver" value="Microsoft Access Driver (*.mdb)" />
    <add key="OdbcDBQ" value="d:\test.mdb" />
      
</appSettings>

     现在一切OK,大家可以通过改变Web.config中的变量来使用不同的数据库连接方式(SqlServer专用连接、OleDb连接和Odbc连接)连接不同的数据库,同时整个使用仍通过DbAccess,不受任何影响。
============================================================

今天看了看设计模式中的工场模式,感觉还不错,一时兴起,便将我原来利用简单工场模式写的一个操作数据库的类大至改成了工场模式,算是加深我对工场模式的理解吧。下面来看看实现过程: 

一。采用工场模式实现对Connection对象的操作 

None.gif using  System; 
None.gif
using  System.Data; 
None.gif
using  System.Data.Odbc; 
None.gif
using  System.Data.OleDb; 
None.gif
using  System.Data.SqlClient; 
None.gif 
None.gif
namespace  DBFactory 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>抽象Connection工場類</summary> 
InBlock.gif    public abstract class ConnectionFactory 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        
protected string connectionString; 
InBlock.gif 
InBlock.gif        
public ConnectionFactory(string connString) 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            
this.connectionString = connString; 
ExpandedSubBlockEnd.gif        }
 
InBlock.gif 
InBlock.gif        
public abstract IDbConnection GetConnection(); 
ExpandedSubBlockEnd.gif    }
 
InBlock.gif 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>實現SqlConnection對象的具體工作類</summary> 
InBlock.gif    public class SqlConnection : ConnectionFactory 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public SqlConnection() : this(null)dot.gif{} 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public SqlConnection(string connString) : base(connString)dot.gif{} 
InBlock.gif 
InBlock.gif        
public override IDbConnection GetConnection() 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            
if(connectionString!=null
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif
InBlock.gif                
return new System.Data.SqlClient.SqlConnection(connectionString); 
ExpandedSubBlockEnd.gif            }
 
InBlock.gif            
else 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif
InBlock.gif                
return new System.Data.SqlClient.SqlConnection(); 
ExpandedSubBlockEnd.gif            }
 
ExpandedSubBlockEnd.gif        }
 
ExpandedSubBlockEnd.gif    }
 
InBlock.gif 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>實現OleDbConnection對象的具體工場類</summary> 
InBlock.gif    public class AccessConnection :ConnectionFactory 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public AccessConnection() : this(null)dot.gif{} 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public AccessConnection(string connString) :base(connString)dot.gif{} 
InBlock.gif 
InBlock.gif        
public override IDbConnection GetConnection() 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            
if(connectionString!=null
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif
InBlock.gif                
return new OleDbConnection(connectionString); 
ExpandedSubBlockEnd.gif            }
 
InBlock.gif            
else 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif
InBlock.gif                
return new OleDbConnection(); 
ExpandedSubBlockEnd.gif            }
 
ExpandedSubBlockEnd.gif        }
 
ExpandedSubBlockEnd.gif    }
 
ExpandedBlockEnd.gif}
 
None.gif

connection.jpg 
二。采用工场模式实现对Command对象的操作 

None.gif using  System; 
None.gif
using  System.Data; 
None.gif
using  System.Data.Common; 
None.gif
using  System.Data.OleDb; 
None.gif
using  System.Data.SqlClient; 
None.gif 
None.gif
namespace  DBFactory 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>抽象CommandFactory類</summary> 
InBlock.gif    public abstract class CommandFactory 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        
protected string commandText; 
InBlock.gif        
protected IDbConnection iConn; 
InBlock.gif 
InBlock.gif        
public CommandFactory(IDbConnection conn,string commText) 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            
this.iConn = conn; 
InBlock.gif            
this.commandText = commText; 
ExpandedSubBlockEnd.gif        }
 
InBlock.gif 
InBlock.gif        
public abstract IDbCommand GetCommand(); 
ExpandedSubBlockEnd.gif    }
 
InBlock.gif 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>實現SqlCommand對象的具體類</summary> 
InBlock.gif    public class SqlCommand : CommandFactory 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public SqlCommand(IDbConnection conn,string commText) : base(conn,commText)dot.gif{} 
InBlock.gif 
InBlock.gif        
public override IDbCommand GetCommand() 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            
return new System.Data.SqlClient.SqlCommand(commandText,(System.Data.SqlClient.SqlConnection)iConn); 
ExpandedSubBlockEnd.gif        }
 
ExpandedSubBlockEnd.gif    }
 
InBlock.gif 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>實現OleDbCommand對象的具體類</summary> 
InBlock.gif    public class AccessCommand : CommandFactory 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public AccessCommand(IDbConnection conn,string commText) : base(conn,commText)dot.gif{} 
InBlock.gif 
InBlock.gif        
public override IDbCommand GetCommand() 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            
return new OleDbCommand(commandText,(OleDbConnection)iConn); 
ExpandedSubBlockEnd.gif        }
 
ExpandedSubBlockEnd.gif    }
 
ExpandedBlockEnd.gif}
 
None.gif

 

 

 

command.jpg 
三。采用工场模式实现对DataAdapter对象的操作 

None.gif using  System; 
None.gif
using  System.Data; 
None.gif
using  System.Data.Common; 
None.gif
using  System.Data.OleDb; 
None.gif
using  System.Data.SqlClient; 
None.gif 
None.gif
namespace  DBFactory 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>抽象DataAdapterFactory工場類</summary> 
InBlock.gif    public abstract class DataAdapterFactory 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        
protected IDbCommand iComm; 
InBlock.gif 
InBlock.gif        
public DataAdapterFactory(IDbCommand comm) 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            
this.iComm = comm; 
ExpandedSubBlockEnd.gif        }
 
InBlock.gif 
InBlock.gif        
public abstract DbDataAdapter GetDataAdapter(); 
ExpandedSubBlockEnd.gif    }
 
InBlock.gif 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>實現SqlDataAdapter對象的具體類</summary> 
InBlock.gif    public class SqlDataAdapter : DataAdapterFactory 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public SqlDataAdapter(IDbCommand comm) : base(comm)dot.gif{} 
InBlock.gif 
InBlock.gif        
public override DbDataAdapter GetDataAdapter() 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            
return new System.Data.SqlClient.SqlDataAdapter((System.Data.SqlClient.SqlCommand)iComm); 
ExpandedSubBlockEnd.gif        }
 
ExpandedSubBlockEnd.gif    }
 
InBlock.gif 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//// <summary>實現OleDbDataAdapter對象的具體類</summary> 
InBlock.gif    public class AccessDataAdapter : DataAdapterFactory 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public AccessDataAdapter(IDbCommand comm) : base(comm)dot.gif{} 
InBlock.gif 
InBlock.gif        
public override DbDataAdapter GetDataAdapter() 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            
return new OleDbDataAdapter((OleDbCommand)iComm); 
ExpandedSubBlockEnd.gif        }
 
InBlock.gif 
ExpandedSubBlockEnd.gif    }
 
ExpandedBlockEnd.gif}
 
None.gif

DataAdapter.jpg

四。这里利用简单工场模式来返回以上的抽象工场对象 

None.gif using  System; 
None.gif
using  System.Data; 
None.gif
using  System.Data.Common; 
None.gif
using  System.Data.OleDb; 
None.gif
using  System.Data.SqlClient; 
None.gif 
None.gif
namespace  DBFactory 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif    
public class SimpleFactory 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public SimpleFactory()dot.gif{} 
InBlock.gif 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>返回抽象的ConnectionFactory工場對象</summary> 
InBlock.gif        public static ConnectionFactory GetConnFactory(string connString,string dbType) 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            ConnectionFactory factory; 
InBlock.gif            
switch(dbType.ToUpper()) 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif
InBlock.gif                
case "SQL"
InBlock.gif                    factory 
= new DBFactory.SqlConnection(connString); 
InBlock.gif                    
break
InBlock.gif                
case "ACCESS"
InBlock.gif                    factory 
= new DBFactory.AccessConnection(connString); 
InBlock.gif                    
break
InBlock.gif                
default
InBlock.gif                    factory 
= null
InBlock.gif                    
break
ExpandedSubBlockEnd.gif            }
 
InBlock.gif            
return factory; 
ExpandedSubBlockEnd.gif        }
 
InBlock.gif 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>返回抽象的CommandFactory工場對象</summary> 
InBlock.gif        public static CommandFactory GetCommFactory(IDbConnection conn,string commText,string dbType) 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            CommandFactory factory; 
InBlock.gif            
switch(dbType.ToUpper()) 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif
InBlock.gif                
case "SQL"
InBlock.gif                    factory 
= new DBFactory.SqlCommand(conn,commText); 
InBlock.gif                    
break
InBlock.gif                
case "ACCESS"
InBlock.gif                    factory 
= new DBFactory.AccessCommand(conn,commText); 
InBlock.gif                    
break
InBlock.gif                
default
InBlock.gif                    factory 
= null
InBlock.gif                    
break
ExpandedSubBlockEnd.gif            }
 
InBlock.gif            
return factory; 
ExpandedSubBlockEnd.gif        }
 
InBlock.gif 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>返回抽象的DataAdapterFactory工場對象</summary> 
InBlock.gif        public static DataAdapterFactory GetDataAdapterFactory(IDbCommand comm,string dbType) 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            DataAdapterFactory factory; 
InBlock.gif            
switch(dbType.ToUpper()) 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif
InBlock.gif                
case "SQL"
InBlock.gif                    factory 
= new DBFactory.SqlDataAdapter(comm); 
InBlock.gif                    
break
InBlock.gif                
case "ACCESS"
InBlock.gif                    factory 
= new DBFactory.AccessDataAdapter(comm); 
InBlock.gif                    
break
InBlock.gif                
default
InBlock.gif                    factory 
= null
InBlock.gif                    
break
ExpandedSubBlockEnd.gif            }
 
InBlock.gif            
return factory; 
ExpandedSubBlockEnd.gif        }
 
ExpandedSubBlockEnd.gif    }
 
ExpandedBlockEnd.gif}
 
None.gif

simplefactory.jpg 
五。封装的操作数据库存的类 

None.gif using  System; 
None.gif
using  System.Data; 
None.gif
using  System.Data.Common; 
None.gif
using  System.Data.OleDb; 
None.gif
using  System.Data.SqlClient; 
None.gif
using  System.Configuration; 
None.gif 
None.gif
namespace  DBFactory 
ExpandedBlockStart.gifContractedBlock.gif
dot.gif
InBlock.gif    
public class ExecuteDB 
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif
InBlock.gif        
private static string connectionString; 
InBlock.gif        
private static string dbType; 
InBlock.gif 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
public ExecuteDB()dot.gif{} 
InBlock.gif 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>數據庫連接字符串</summary> 
InBlock.gif        public static string ConnectionString 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            
get 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif
InBlock.gif                
if(connectionString==null) connectionString = ConfigurationSettings.AppSettings["ConnectionString"]; 
InBlock.gif                
return connectionString; 
ExpandedSubBlockEnd.gif            }
 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
setdot.gif{connectionString = value;} 
ExpandedSubBlockEnd.gif        }
 
InBlock.gif 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>數據庫類型</summary> 
InBlock.gif        public static string DBType 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            
get 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif
InBlock.gif                
if(dbType==null) dbType = ConfigurationSettings.AppSettings["DataBaseType"]; 
InBlock.gif                
return dbType; 
ExpandedSubBlockEnd.gif            }
 
ExpandedSubBlockStart.gifContractedSubBlock.gif            
setdot.gif{dbType=value;} 
ExpandedSubBlockEnd.gif        }
 
InBlock.gif 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
/**//// <summary>執行SQL語句返回DataSet</summary> 
InBlock.gif        public static DataSet ExcuteSql(string sqlString) 
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif
InBlock.gif            DataSet ds 
= new DataSet(); 
InBlock.gif            ConnectionFactory objConn 
= SimpleFactory.GetConnFactory(ConnectionString,DBType); 
InBlock.gif            IDbConnection iConn 
= objConn.GetConnection(); 
InBlock.gif            iConn.Open(); 
InBlock.gif            CommandFactory objComm 
= SimpleFactory.GetCommFactory(iConn,sqlString,DBType); 
InBlock.gif            IDbCommand iComm 
= objComm.GetCommand(); 
InBlock.gif            DataAdapterFactory objAdapter 
= SimpleFactory.GetDataAdapterFactory(iComm,DBType); 
InBlock.gif            DbDataAdapter dataAdaper 
= objAdapter.GetDataAdapter(); 
InBlock.gif            dataAdaper.Fill(ds); 
InBlock.gif            iComm.Dispose(); 
InBlock.gif            iConn.Close(); 
InBlock.gif            iConn.Dispose(); 
InBlock.gif            
return ds; 
ExpandedSubBlockEnd.gif        }
 
ExpandedSubBlockEnd.gif    }
 
ExpandedBlockEnd.gif}
 
None.gif


上面對具體的數據庫的選擇采用的是簡單工場模式來實現的(因工場模式中的具體類只能實現具體的對象,感覺不好實現) 

實現方法: 

None.gif string  connString  =  " data source=192.168.1.9;initial catalog=sqldll;persist security info=False;user id=sa;password=123456;workstation id=Server;packet size=4096 "
None.gif            
string  commString  =  " select * from tbl_Vip "
None.gif 
None.gif            ExecuteDB.ConnectionString 
=  connString; 
None.gif            ExecuteDB.DBType 
=  " sql "
None.gif            DataGrid1.DataSource
= ExecuteDB.ExcuteSql(commString); 
None.gif            DataGrid1.DataBind();
本文转自kenty博客园博客,原文链接 http://www.cnblogs.com/kentyshang/archive/2007/07/25/830424.html如需转载请自行联系原作者

kenty
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
1月前
|
SQL 关系型数据库 MySQL
2024年阿里云数据库创建_数据库账号密码和连接教程
阿里云数据库怎么使用?阿里云百科整理阿里云数据库从购买到使用全流程,阿里云支持MySQL、SQL Server、PostgreSQL和MariaDB等数据库引擎,阿里云数据库具有高可用、高容灾特性,阿里云提供数据库备份、恢复、迁移全套解决方案。详细阿里云数据库购买和使用流程方法如下
|
1月前
|
数据采集 Java 关系型数据库
Java代码高效连接数据库
Java代码高效连接数据库
18 2
|
1月前
|
Ubuntu 关系型数据库 MySQL
【MySQL】Navicat/SQLyog连接Ubuntu中的数据库(MySQL)
【MySQL】Navicat/SQLyog连接Ubuntu中的数据库(MySQL)
|
28天前
|
SQL 关系型数据库 MySQL
阿里云MySQL数据库价格、购买、创建账号密码和连接数据库教程
阿里云数据库使用指南:购买MySQL、SQL Server等RDS实例,选择配置和地区,完成支付。创建数据库和账号,设置权限。通过DMS登录数据库,使用账号密码访问。同地域VPC内的ECS需将IP加入白名单以实现内网连接。参考链接提供详细步骤。
367 3
|
1月前
|
SQL 关系型数据库 MySQL
用 Python 连接数据库并进行查询。
【2月更文挑战第12天】【2月更文挑战第32篇】用 Python 连接数据库并进行查询。
|
5天前
|
JavaScript 关系型数据库 MySQL
❤Nodejs 第二章(Node连接本地数据库)
【4月更文挑战第2天】本文介绍了如何使用Node.js连接本地MySQL数据库。首先,提到了在MySQL官网下载安装数据库和使用Navicat for MySQL进行数据库管理。接着,通过`yarn add mysql`在项目中安装数据库依赖。然后,创建`app.js`文件,设置数据库连接参数,并建立连接进行查询操作。遇到导入模块的错误后,修改导入方式为CommonJS语法。
19 1
|
7天前
|
SQL 监控 关系型数据库
PG数据库释放闲置连接
PG数据库释放闲置连接
13 0
|
17天前
|
弹性计算 关系型数据库 MySQL
阿里云数据库服务器价格表,数据库创建、连接和使用教程
阿里云数据库使用流程包括购买和管理。选择所需数据库类型如MySQL,完成实名认证后购买,配置CPU、内存和存储。确保数据库地域与ECS相同以允许内网连接。创建数据库和账号,设置权限。通过DMS登录数据库,使用账号密码连接。同一VPC内的ECS需添加至白名单以进行内网通信。参考官方文档进行详细操作。
77 3
|
18天前
|
网络协议 数据库连接 网络安全
DM数据库连接数据库时报:创建sokect连接失败
DM数据库连接数据库时报:创建sokect连接失败
12 0
|
1月前
|
SQL 关系型数据库 MySQL
阿里云数据库使用方法,从购买、创建数据库账号密码到连接数据库全流程
阿里云数据库使用方法,从购买、创建数据库账号密码到连接数据库全流程,阿里云数据库怎么使用?阿里云百科整理阿里云数据库从购买到使用全流程,阿里云支持MySQL、SQL Server、PostgreSQL和MariaDB等数据库引擎,阿里云数据库具有高可用、高容灾特性,阿里云提供数据库备份、恢复、迁移全套解决方案
337 0