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

1、新建一个 数据库访问基类DBHandler
    /// 
    /// 数据库访问基类
    /// 
    public abstract class DBHandler
    {
        public DBHandler() { }

        #region 需要在子类中初始化的与数据库相关的特征类

        protected DbConnection dbConnection = null; //连接对象
        protected DbTransaction dbTransaction = null; //事务对象
        protected abstract DbCommand CreateCommand(); //从子类中构建DbCommand对象
        protected abstract DbDataAdapter CreateAdapter(); //从子类中构建DbDataAdapter对象
        protected abstract void BuilderCommand(DbDataAdapter adapter); //用于Update方法,构建DbDataAdapter中的UpdateCommand/InsertCommand/DeleteCommand
        protected abstract int GetTotalCount(); //用于分页查询,获取总记录数

        #endregion

        #region 子类中要用的数据或方法

        protected List parameters = new List();
        protected bool IsInTransaction = false; //是否处于事务当中
        //用于分页查询,检查当前SQL是否符合基本查询要求
        protected void CheckPageSQL()
        {
            this.CommandType = CommandType.Text;
            if (!this.CommandText.StartsWith("select", true, null))
            {
                throw new Exception("sql语句必须是select开头");
            }
            if (IsInTransaction)
            {
                throw new Exception("分页查询不能在事务中");
            }
        }

        #endregion

        #region  用于输入初始条件的属性和方法

        /// 
        /// sql语句或存储过程名称
        /// 
        public string CommandText { get; set; }

        /// 
        /// 执行类型是SQL还是存储过程
        /// 
        public CommandType CommandType { get; set; }

        /// 
        /// 添加参数,将参数添加到List列表中保存起来
        /// 
        /// 参数名
        /// 参数值
        public void AddParameter(string paraName, string paraValue)
        {
            this.parameters.Add(new Parameter(paraName,paraValue));
        }

        /// 
        /// 清空当前参数列表
        /// 
        public void ClearParameter()
        {
            this.parameters.Clear();
        }

        /// 
        /// 用于分页查询,获取查询到的总记录数
        /// 
        public int TotalCount
        {
            get
            {
                return this.GetTotalCount();
            }
        }

        #endregion

        #region 获取数据库的返回值

        /// 
        /// 获取执行结果的第一行第一列的值
        /// 
        /// 
        public object ExecuteScalar()
        {
            try
            {
                if (dbConnection.State != ConnectionState.Open)
                {
                    dbConnection.Open();
                }
                DbCommand cmd = this.CreateCommand();
                object r = cmd.ExecuteScalar();
                if (!this.IsInTransaction)
                {
                    dbConnection.Close();
                }
                return r;
            }
            catch (Exception ex)
            {
                this.dbConnection.Close();
                throw new Exception(ex.Message);
            }
        }

        /// 
        /// 执行没有数据集的命令 Update/Delete/Insert
        /// 
        /// 
        public int ExecuteNonQuery()
        {
            try
            {
                if (this.dbConnection.State != ConnectionState.Open)
                {
                    this.dbConnection.Open();
                }
                DbCommand cmd = this.CreateCommand();
                int r = cmd.ExecuteNonQuery();
                if (!IsInTransaction)
                {
                    dbConnection.Close();
                }
                return r;
            }
            catch (Exception ex)
            {
                dbConnection.Close();
                throw new Exception(ex.Message);
            }
        }

        /// 
        /// 执行结果的DataTable集
        /// 
        /// 
        public DataTable ExecuteDataTable()
        {
            try
            {
                if (this.dbConnection.State != ConnectionState.Open)
                {
                    this.dbConnection.Open();
                }
                DbDataAdapter adapter = this.CreateAdapter();
                DataTable dt = new DataTable();
                adapter.FillSchema(dt, SchemaType.Mapped);
                adapter.Fill(dt);
                if (!IsInTransaction)
                {
                    dbConnection.Close();
                }
                return dt;
            }
            catch (Exception ex)
            {
                dbConnection.Close();
                throw new Exception(ex.Message);
            }
        }

        /// 
        /// 用于分页查询,获取指定页码的数据集
        /// 
        /// 每页记录数
        /// 当前页码
        /// 指定页的记录集
        public abstract DataTable ExecuteDataTable(int pageSize,int currentPageIndex);

        #endregion

        #region 将DataTable更新到数据库中

        public int UpdateData(DataTable dt)
        {
            try
            {
                if (this.dbConnection.State != ConnectionState.Open)
                {
                    this.dbConnection.Open();
                }
                DbDataAdapter adapter = this.CreateAdapter();
                if (this.CommandType == CommandType.StoredProcedure)
                {
                    this.CommandType = CommandType.Text;
                }
                this.BuilderCommand(adapter);
                int r = adapter.Update(dt);
                if (!IsInTransaction)
                {
                    dbConnection.Close();
                }
                return r;
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        }

        #endregion

        #region 事务处理

        /// 
        /// 开始一个事务
        /// 
        public void BegionTransaction()
        {
            try
            {
                if (this.dbConnection.State != ConnectionState.Open)
                {
                    this.dbConnection.Open();
                }
                this.dbConnection.BeginTransaction();
                this.IsInTransaction = true;
            }
            catch (Exception ex)
            {
                this.dbConnection.Close();
                this.IsInTransaction = false;
                throw ex;
            }
        }

        /// 
        /// 回滚一个事务
        /// 
        public void RollbackTransaction()
        {
            try
            {
                this.dbTransaction.Rollback();
                this.dbConnection.Close();
                this.IsInTransaction = false;
            }
            catch (Exception ex)
            {
                this.dbConnection.Close();
                this.IsInTransaction = false;
                throw ex;
            }
        }

        /// 
        /// 提交一个事务
        /// 
        public void CommitTransaction()
        {
            try
            {
                this.dbTransaction.Commit();
                this.dbConnection.Close();
                this.IsInTransaction = false;
            }
            catch (Exception ex)
            {
                this.dbConnection.Close();
                this.IsInTransaction = false;
                throw ex;
            }
        }

        #endregion

        #region 建立数据行对象


        #endregion

        #region 对序列的读取

        /// 
        /// 获取序列的值,对于非oracle数据库,必须建立一个名为System_Sequence的表,表的字段为(Name(nvarchar,50),Value(int))
        /// 
        /// 
        /// 
        public abstract int GetSequenceValue(string sequenceName);

        #endregion
    }
2、新建一个参数类
   public class Parameter
    {
       public string Name = string.Empty;
       public object Value = null;
       public Parameter(string name,string value)
       {
           this.Name = name;
           this.Value = value;
       }
    }
3、新建一个Sqlser数据库访问类
   internal class DBhANDlerSQLServer:DBHandler
    {
        public DBhANDlerSQLServer(string connectionString)
            : base()
        {
            this.dbConnection = new SqlConnection(connectionString);
        }
        protected override DbCommand CreateCommand()
        {
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = (SqlConnection)this.dbConnection;
            if (this.IsInTransaction)
            {
                cmd.Transaction = (SqlTransaction)this.dbTransaction;
            }
            if (this.CommandType == CommandType.TableDirect)
            {
                cmd.CommandType = CommandType.Text;
                cmd.CommandText = string.Format("select * from {0}", this.CommandText);
            }
            else
            {
                cmd.CommandType=CommandType;
                cmd.CommandText = CommandText;
            }
            if (this.parameters.Count > 0)
            {
                foreach (Parameter p in parameters)
                {
                    cmd.Parameters.AddWithValue(p.Name, p.Value);
                }
            }
            return cmd;
        }

        protected override DbDataAdapter CreateAdapter()
        {
            SqlCommand cmd = (SqlCommand)this.CreateCommand();
            SqlDataAdapter adapter = new SqlDataAdapter(cmd);
            return adapter;
        }

        protected override void BuilderCommand(DbDataAdapter adapter)
        {
            new SqlCommandBuilder((SqlDataAdapter)adapter);
        }

        protected override int GetTotalCount()
        {
            this.CheckPageSQL();
            string sql = this.CommandText; //保留原始SQL
            string sqlWithOutOrderField = string.Empty; //将原始SQL语句去掉 order by 后的部分,用于查询总记录数
            int startIndex = sql.LastIndexOf("order by");
            if (startIndex >= 0)
            {
                sqlWithOutOrderField = sql.Substring(0, startIndex);
            }
            else
            {
                sqlWithOutOrderField = sql;
            }
            this.CommandText = string.Format("select count(*)from ({0}) t1",sqlWithOutOrderField);
            int r = int.Parse(this.ExecuteScalar().ToString());
            this.CommandText = sql;
            return r;
        }

        public override DataTable ExecuteDataTable(int pageSize, int currentPageIndex)
        {
            this.CheckPageSQL();
            string sql = this.CommandText; //保留原始SQL
            string orderBy = string.Empty; //将order by字句保留下来
            string sqlWithSelectAndOrder = sql.Substring(6); //去掉select以及整个order by
            int startIndex = sqlWithSelectAndOrder.ToLower().LastIndexOf("order by");
            if (startIndex > 0)
            {
                orderBy = sqlWithSelectAndOrder.Substring(startIndex);
                sqlWithSelectAndOrder = sqlWithSelectAndOrder.Substring(0, startIndex);
            }
            else
            {
                throw new Exception("sql的分页查询必须有order by");
            }
            if (pageSize == 0) //返回所有数据
            {
                this.CommandText = sql;
                this.ExecuteDataTable();
            }
            DataTable dt = new DataTable();
            if (currentPageIndex == 1) //如果当前页为1
            {
                this.CommandText = string.Format("select top {0} {1} {2}", pageSize, sqlWithSelectAndOrder, orderBy);
                dt = this.ExecuteDataTable();
            }
            else  //适合sqlserver2005及以上的版本,但必须带 order by子句
            {
                StringBuilder sb = new StringBuilder();
                sb.Append("select * from ");
                sb.AppendFormat("(select Row_Number() over ({0}) as RowNum,{1})t1",orderBy,sqlWithSelectAndOrder);
                sb.AppendFormat(" where RowNum between {0} and {1}",pageSize*(currentPageIndex-1),pageSize*currentPageIndex-1);
                this.CommandText = sb.ToString();
                dt = this.ExecuteDataTable();
            }
            this.CommandText = sql;
            return dt;
        }

        public override int GetSequenceValue(string sequenceName)
        {
            //sqlserver 先要建立配套的系列表 System_Sequence
            /*建表语句:if not exists(select * from sysobjects where Name='System_Sequence')
            create table System_Sequence
            {
            Name varchar(50),
            Value int,
            constraint "PK_SsystemSequence" primary key(Name)
            };
            insert into System_Sequence(Name,Value) values('Sequence_<表名>',0); */

            this.CommandType = CommandType.Text;
            this.BegionTransaction();
            this.CommandText = string.Format("Update System_Sequence set Value=Value+1 where Name='{0}'", sequenceName);
            this.ExecuteNonQuery();
            this.CommandText = string.Format("select Value from System_Sequence where Name='{0}'", sequenceName);
            int r = this.ExecuteNonQuery();
            this.CommitTransaction();
            return r;
        }
    }
4、新建一个工厂类
    public enum DatabaseType
    {
        SqlServer = 1,
        Oracle = 2,
        ODBC = 3,
        OLEDB = 4
    }

   public class DBHandlerFactory
    {
       //禁止产生类的实例
       private DBHandlerFactory() { }

       /// 
       /// 读取webconfig中的ConnectionString配置节点构造实例
       /// 
       /// 
       /// 
       public static DBHandler GetHandler(string connStr)
       {
          ConnectionStringSettings  ccs = ConfigurationManager.ConnectionStrings[connStr];
          string providerName = ccs.ProviderName.ToLower();
          DatabaseType dbType = DatabaseType.SqlServer;
          switch (providerName)
          {
              case "":
              case "sqlserver":
              case "system.data.sqlclient":
                  dbType = DatabaseType.SqlServer;
                  break;
              case "oracle":
              case"system.data.oracleclient":
                  dbType = DatabaseType.Oracle;
                  break;
              case "odbc":
              case "system.data.odbc":
                  dbType = DatabaseType.ODBC;
                  break;
              case "oledb":
              case "system.data.oledb":
                  dbType = DatabaseType.OLEDB;
                  break;
              default:
                  throw new Exception("请按照格式定义ProviderName属性");
          }
          switch (dbType)
          {
              case DatabaseType.SqlServer:
                  return new DBhANDlerSQLServer(ccs.ConnectionString); 
              case DatabaseType.Oracle:
                  return null;
              case DatabaseType.ODBC:
                  return null;
              case DatabaseType.OLEDB:
                  return null;
              default:
                  return null;
          }
       }

       /// 
       /// 直接以连接字符串和数据库类型构造
       /// 
       /// 
       /// 
       /// 
       public static DBHandler GetHandler(string connStr,DatabaseType dbType)
       {
           switch (dbType)
           {
               case DatabaseType.SqlServer:
                   return new DBhANDlerSQLServer(connStr);
               case DatabaseType.Oracle:
                   return null;
               case DatabaseType.ODBC:
                   return null;
               case DatabaseType.OLEDB:
                   return null;
               default:
                   return null;
           }
       }
    }
5.....其它的数据库访问类,可以参照sqlserver数据库访问类创建。



你可能感兴趣的:(ASP.NET,WebForm开发)