简单工厂模式构建数据访问层以实现多种数据库之间的切换

1、新建一个 数据库访问基类DBHandler
  1. ///   
  2. /// 数据库访问基类  
  3. ///   
  4. public abstract class DBHandler  
  5. {  
  6.     public DBHandler() { }  
  7.  
  8.     #region 需要在子类中初始化的与数据库相关的特征类  
  9.   
  10.     protected DbConnection dbConnection = null//连接对象  
  11.     protected DbTransaction dbTransaction = null//事务对象  
  12.     protected abstract DbCommand CreateCommand(); //从子类中构建DbCommand对象  
  13.     protected abstract DbDataAdapter CreateAdapter(); //从子类中构建DbDataAdapter对象  
  14.     protected abstract void BuilderCommand(DbDataAdapter adapter); //用于Update方法,构建DbDataAdapter中的UpdateCommand/InsertCommand/DeleteCommand  
  15.     protected abstract int GetTotalCount(); //用于分页查询,获取总记录数  
  16.  
  17.     #endregion  
  18.  
  19.     #region 子类中要用的数据或方法  
  20.   
  21.     protected List parameters = new List();  
  22.     protected bool IsInTransaction = false//是否处于事务当中  
  23.     //用于分页查询,检查当前SQL是否符合基本查询要求  
  24.     protected void CheckPageSQL()  
  25.     {  
  26.         this.CommandType = CommandType.Text;  
  27.         if (!this.CommandText.StartsWith("select"truenull))  
  28.         {  
  29.             throw new Exception("sql语句必须是select开头");  
  30.         }  
  31.         if (IsInTransaction)  
  32.         {  
  33.             throw new Exception("分页查询不能在事务中");  
  34.         }  
  35.     }  
  36.  
  37.     #endregion  
  38.  
  39.     #region  用于输入初始条件的属性和方法  
  40.   
  41.     ///   
  42.     /// sql语句或存储过程名称  
  43.     ///   
  44.     public string CommandText { getset; }  
  45.   
  46.     ///   
  47.     /// 执行类型是SQL还是存储过程  
  48.     ///   
  49.     public CommandType CommandType { getset; }  
  50.   
  51.     ///   
  52.     /// 添加参数,将参数添加到List列表中保存起来  
  53.     ///   
  54.     /// 参数名  
  55.     /// 参数值  
  56.     public void AddParameter(string paraName, string paraValue)  
  57.     {  
  58.         this.parameters.Add(new Parameter(paraName,paraValue));  
  59.     }  
  60.   
  61.     ///   
  62.     /// 清空当前参数列表  
  63.     ///   
  64.     public void ClearParameter()  
  65.     {  
  66.         this.parameters.Clear();  
  67.     }  
  68.   
  69.     ///   
  70.     /// 用于分页查询,获取查询到的总记录数  
  71.     ///   
  72.     public int TotalCount  
  73.     {  
  74.         get  
  75.         {  
  76.             return this.GetTotalCount();  
  77.         }  
  78.     }  
  79.  
  80.     #endregion  
  81.  
  82.     #region 获取数据库的返回值  
  83.   
  84.     ///   
  85.     /// 获取执行结果的第一行第一列的值  
  86.     ///   
  87.     ///   
  88.     public object ExecuteScalar()  
  89.     {  
  90.         try  
  91.         {  
  92.             if (dbConnection.State != ConnectionState.Open)  
  93.             {  
  94.                 dbConnection.Open();  
  95.             }  
  96.             DbCommand cmd = this.CreateCommand();  
  97.             object r = cmd.ExecuteScalar();  
  98.             if (!this.IsInTransaction)  
  99.             {  
  100.                 dbConnection.Close();  
  101.             }  
  102.             return r;  
  103.         }  
  104.         catch (Exception ex)  
  105.         {  
  106.             this.dbConnection.Close();  
  107.             throw new Exception(ex.Message);  
  108.         }  
  109.     }  
  110.   
  111.     ///   
  112.     /// 执行没有数据集的命令 Update/Delete/Insert  
  113.     ///   
  114.     ///   
  115.     public int ExecuteNonQuery()  
  116.     {  
  117.         try  
  118.         {  
  119.             if (this.dbConnection.State != ConnectionState.Open)  
  120.             {  
  121.                 this.dbConnection.Open();  
  122.             }  
  123.             DbCommand cmd = this.CreateCommand();  
  124.             int r = cmd.ExecuteNonQuery();  
  125.             if (!IsInTransaction)  
  126.             {  
  127.                 dbConnection.Close();  
  128.             }  
  129.             return r;  
  130.         }  
  131.         catch (Exception ex)  
  132.         {  
  133.             dbConnection.Close();  
  134.             throw new Exception(ex.Message);  
  135.         }  
  136.     }  
  137.   
  138.     ///   
  139.     /// 执行结果的DataTable集  
  140.     ///   
  141.     ///   
  142.     public DataTable ExecuteDataTable()  
  143.     {  
  144.         try  
  145.         {  
  146.             if (this.dbConnection.State != ConnectionState.Open)  
  147.             {  
  148.                 this.dbConnection.Open();  
  149.             }  
  150.             DbDataAdapter adapter = this.CreateAdapter();  
  151.             DataTable dt = new DataTable();  
  152.             adapter.FillSchema(dt, SchemaType.Mapped);  
  153.             adapter.Fill(dt);  
  154.             if (!IsInTransaction)  
  155.             {  
  156.                 dbConnection.Close();  
  157.             }  
  158.             return dt;  
  159.         }  
  160.         catch (Exception ex)  
  161.         {  
  162.             dbConnection.Close();  
  163.             throw new Exception(ex.Message);  
  164.         }  
  165.     }  
  166.   
  167.     ///   
  168.     /// 用于分页查询,获取指定页码的数据集  
  169.     ///   
  170.     /// 每页记录数  
  171.     /// 当前页码  
  172.     /// 指定页的记录集  
  173.     public abstract DataTable ExecuteDataTable(int pageSize,int currentPageIndex);  
  174.  
  175.     #endregion  
  176.  
  177.     #region 将DataTable更新到数据库中  
  178.   
  179.     public int UpdateData(DataTable dt)  
  180.     {  
  181.         try  
  182.         {  
  183.             if (this.dbConnection.State != ConnectionState.Open)  
  184.             {  
  185.                 this.dbConnection.Open();  
  186.             }  
  187.             DbDataAdapter adapter = this.CreateAdapter();  
  188.             if (this.CommandType == CommandType.StoredProcedure)  
  189.             {  
  190.                 this.CommandType = CommandType.Text;  
  191.             }  
  192.             this.BuilderCommand(adapter);  
  193.             int r = adapter.Update(dt);  
  194.             if (!IsInTransaction)  
  195.             {  
  196.                 dbConnection.Close();  
  197.             }  
  198.             return r;  
  199.         }  
  200.         catch (Exception ex)  
  201.         {  
  202.             throw new Exception(ex.Message);  
  203.         }  
  204.     }  
  205.  
  206.     #endregion  
  207.  
  208.     #region 事务处理  
  209.   
  210.     ///   
  211.     /// 开始一个事务  
  212.     ///   
  213.     public void BegionTransaction()  
  214.     {  
  215.         try  
  216.         {  
  217.             if (this.dbConnection.State != ConnectionState.Open)  
  218.             {  
  219.                 this.dbConnection.Open();  
  220.             }  
  221.             this.dbConnection.BeginTransaction();  
  222.             this.IsInTransaction = true;  
  223.         }  
  224.         catch (Exception ex)  
  225.         {  
  226.             this.dbConnection.Close();  
  227.             this.IsInTransaction = false;  
  228.             throw ex;  
  229.         }  
  230.     }  
  231.   
  232.     ///   
  233.     /// 回滚一个事务  
  234.     ///   
  235.     public void RollbackTransaction()  
  236.     {  
  237.         try  
  238.         {  
  239.             this.dbTransaction.Rollback();  
  240.             this.dbConnection.Close();  
  241.             this.IsInTransaction = false;  
  242.         }  
  243.         catch (Exception ex)  
  244.         {  
  245.             this.dbConnection.Close();  
  246.             this.IsInTransaction = false;  
  247.             throw ex;  
  248.         }  
  249.     }  
  250.   
  251.     ///   
  252.     /// 提交一个事务  
  253.     ///   
  254.     public void CommitTransaction()  
  255.     {  
  256.         try  
  257.         {  
  258.             this.dbTransaction.Commit();  
  259.             this.dbConnection.Close();  
  260.             this.IsInTransaction = false;  
  261.         }  
  262.         catch (Exception ex)  
  263.         {  
  264.             this.dbConnection.Close();  
  265.             this.IsInTransaction = false;  
  266.             throw ex;  
  267.         }  
  268.     }  
  269.  
  270.     #endregion  
  271.  
  272.     #region 建立数据行对象  
  273.  
  274.  
  275.     #endregion  
  276.  
  277.     #region 对序列的读取  
  278.   
  279.     ///   
  280.     /// 获取序列的值,对于非oracle数据库,必须建立一个名为System_Sequence的表,表的字段为(Name(nvarchar,50),Value(int))  
  281.     ///   
  282.     ///   
  283.     ///   
  284.     public abstract int GetSequenceValue(string sequenceName);  
  285.  
  286.     #endregion  
  287. }  
2、新建一个参数类
[csharp] view plain copy print?
  1. public class Parameter  
  2.  {  
  3.     public string Name = string.Empty;  
  4.     public object Value = null;  
  5.     public Parameter(string name,string value)  
  6.     {  
  7.         this.Name = name;  
  8.         this.Value = value;  
  9.     }  
  10.  }  
3、新建一个Sqlser数据库访问类
[csharp] view plain copy print?
  1. internal class DBhANDlerSQLServer:DBHandler  
  2.  {  
  3.      public DBhANDlerSQLServer(string connectionString)  
  4.          : base()  
  5.      {  
  6.          this.dbConnection = new SqlConnection(connectionString);  
  7.      }  
  8.      protected override DbCommand CreateCommand()  
  9.      {  
  10.          SqlCommand cmd = new SqlCommand();  
  11.          cmd.Connection = (SqlConnection)this.dbConnection;  
  12.          if (this.IsInTransaction)  
  13.          {  
  14.              cmd.Transaction = (SqlTransaction)this.dbTransaction;  
  15.          }  
  16.          if (this.CommandType == CommandType.TableDirect)  
  17.          {  
  18.              cmd.CommandType = CommandType.Text;  
  19.              cmd.CommandText = string.Format("select * from {0}"this.CommandText);  
  20.          }  
  21.          else  
  22.          {  
  23.              cmd.CommandType=CommandType;  
  24.              cmd.CommandText = CommandText;  
  25.          }  
  26.          if (this.parameters.Count > 0)  
  27.          {  
  28.              foreach (Parameter p in parameters)  
  29.              {  
  30.                  cmd.Parameters.AddWithValue(p.Name, p.Value);  
  31.              }  
  32.          }  
  33.          return cmd;  
  34.      }  
  35.   
  36.      protected override DbDataAdapter CreateAdapter()  
  37.      {  
  38.          SqlCommand cmd = (SqlCommand)this.CreateCommand();  
  39.          SqlDataAdapter adapter = new SqlDataAdapter(cmd);  
  40.          return adapter;  
  41.      }  
  42.   
  43.      protected override void BuilderCommand(DbDataAdapter adapter)  
  44.      {  
  45.          new SqlCommandBuilder((SqlDataAdapter)adapter);  
  46.      }  
  47.   
  48.      protected override int GetTotalCount()  
  49.      {  
  50.          this.CheckPageSQL();  
  51.          string sql = this.CommandText; //保留原始SQL  
  52.          string sqlWithOutOrderField = string.Empty; //将原始SQL语句去掉 order by 后的部分,用于查询总记录数  
  53.          int startIndex = sql.LastIndexOf("order by");  
  54.          if (startIndex >= 0)  
  55.          {  
  56.              sqlWithOutOrderField = sql.Substring(0, startIndex);  
  57.          }  
  58.          else  
  59.          {  
  60.              sqlWithOutOrderField = sql;  
  61.          }  
  62.          this.CommandText = string.Format("select count(*)from ({0}) t1",sqlWithOutOrderField);  
  63.          int r = int.Parse(this.ExecuteScalar().ToString());  
  64.          this.CommandText = sql;  
  65.          return r;  
  66.      }  
  67.   
  68.      public override DataTable ExecuteDataTable(int pageSize, int currentPageIndex)  
  69.      {  
  70.          this.CheckPageSQL();  
  71.          string sql = this.CommandText; //保留原始SQL  
  72.          string orderBy = string.Empty; //将order by字句保留下来  
  73.          string sqlWithSelectAndOrder = sql.Substring(6); //去掉select以及整个order by  
  74.          int startIndex = sqlWithSelectAndOrder.ToLower().LastIndexOf("order by");  
  75.          if (startIndex > 0)  
  76.          {  
  77.              orderBy = sqlWithSelectAndOrder.Substring(startIndex);  
  78.              sqlWithSelectAndOrder = sqlWithSelectAndOrder.Substring(0, startIndex);  
  79.          }  
  80.          else  
  81.          {  
  82.              throw new Exception("sql的分页查询必须有order by");  
  83.          }  
  84.          if (pageSize == 0) //返回所有数据  
  85.          {  
  86.              this.CommandText = sql;  
  87.              this.ExecuteDataTable();  
  88.          }  
  89.          DataTable dt = new DataTable();  
  90.          if (currentPageIndex == 1) //如果当前页为1  
  91.          {  
  92.              this.CommandText = string.Format("select top {0} {1} {2}", pageSize, sqlWithSelectAndOrder, orderBy);  
  93.              dt = this.ExecuteDataTable();  
  94.          }  
  95.          else  //适合sqlserver2005及以上的版本,但必须带 order by子句  
  96.          {  
  97.              StringBuilder sb = new StringBuilder();  
  98.              sb.Append("select * from ");  
  99.              sb.AppendFormat("(select Row_Number() over ({0}) as RowNum,{1})t1",orderBy,sqlWithSelectAndOrder);  
  100.              sb.AppendFormat(" where RowNum between {0} and {1}",pageSize*(currentPageIndex-1),pageSize*currentPageIndex-1);  
  101.              this.CommandText = sb.ToString();  
  102.              dt = this.ExecuteDataTable();  
  103.          }  
  104.          this.CommandText = sql;  
  105.          return dt;  
  106.      }  
  107.   
  108.      public override int GetSequenceValue(string sequenceName)  
  109.      {  
  110.          //sqlserver 先要建立配套的系列表 System_Sequence  
  111.          /*建表语句:if not exists(select * from sysobjects where Name='System_Sequence') 
  112.          create table System_Sequence 
  113.          { 
  114.          Name varchar(50), 
  115.          Value int, 
  116.          constraint "PK_SsystemSequence" primary key(Name) 
  117.          }; 
  118.          insert into System_Sequence(Name,Value) values('Sequence_<表名>',0); */  
  119.   
  120.          this.CommandType = CommandType.Text;  
  121.          this.BegionTransaction();  
  122.          this.CommandText = string.Format("Update System_Sequence set Value=Value+1 where Name='{0}'", sequenceName);  
  123.          this.ExecuteNonQuery();  
  124.          this.CommandText = string.Format("select Value from System_Sequence where Name='{0}'", sequenceName);  
  125.          int r = this.ExecuteNonQuery();  
  126.          this.CommitTransaction();  
  127.          return r;  
  128.      }  
  129.  }  
4、新建一个工厂类
[csharp] view plain copy print?
  1. public enum DatabaseType  
  2. {  
  3.     SqlServer = 1,  
  4.     Oracle = 2,  
  5.     ODBC = 3,  
  6.     OLEDB = 4  
  7. }  
  8.   
  9. ublic class DBHandlerFactory  
  10. {  
  11.    //禁止产生类的实例  
  12.    private DBHandlerFactory() { }  
  13.   
  14.    ///   
  15.    /// 读取webconfig中的ConnectionString配置节点构造实例  
  16.    ///   
  17.    ///   
  18.    ///   
  19.    public static DBHandler GetHandler(string connStr)  
  20.    {  
  21.       ConnectionStringSettings  ccs = ConfigurationManager.ConnectionStrings[connStr];  
  22.       string providerName = ccs.ProviderName.ToLower();  
  23.       DatabaseType dbType = DatabaseType.SqlServer;  
  24.       switch (providerName)  
  25.       {  
  26.           case "":  
  27.           case "sqlserver":  
  28.           case "system.data.sqlclient":  
  29.               dbType = DatabaseType.SqlServer;  
  30.               break;  
  31.           case "oracle":  
  32.           case"system.data.oracleclient":  
  33.               dbType = DatabaseType.Oracle;  
  34.               break;  
  35.           case "odbc":  
  36.           case "system.data.odbc":  
  37.               dbType = DatabaseType.ODBC;  
  38.               break;  
  39.           case "oledb":  
  40.           case "system.data.oledb":  
  41.               dbType = DatabaseType.OLEDB;  
  42.               break;  
  43.           default:  
  44.               throw new Exception("请按照格式定义ProviderName属性");  
  45.       }  
  46.       switch (dbType)  
  47.       {  
  48.           case DatabaseType.SqlServer:  
  49.               return new DBhANDlerSQLServer(ccs.ConnectionString);   
  50.           case DatabaseType.Oracle:  
  51.               return null;  
  52.           case DatabaseType.ODBC:  
  53.               return null;  
  54.           case DatabaseType.OLEDB:  
  55.               return null;  
  56.           default:  
  57.               return null;  
  58.       }  
  59.    }  
  60.   
  61.    ///   
  62.    /// 直接以连接字符串和数据库类型构造  
  63.    ///   
  64.    ///   
  65.    ///   
  66.    ///   
  67.    public static DBHandler GetHandler(string connStr,DatabaseType dbType)  
  68.    {  
  69.        switch (dbType)  
  70.        {  
  71.            case DatabaseType.SqlServer:  
  72.                return new DBhANDlerSQLServer(connStr);  
  73.            case DatabaseType.Oracle:  
  74.                return null;  
  75.            case DatabaseType.ODBC:  
  76.                return null;  
  77.            case DatabaseType.OLEDB:  
  78.                return null;  
  79.            default:  
  80.                return null;  
  81.        }  
  82.    }  
  83. }  
5.....其它的数据库访问类,可以参照sqlserver数据库访问类创建。

你可能感兴趣的:(简单工厂模式构建数据访问层以实现多种数据库之间的切换)