如何做营销型手机网站优化,电子商务网站建设策划书模板,东莞网页设计哪家设计网站好?,企业网站宣传册应该哪个部门做在应用程序的设计中#xff0c;数据库的访问是非常重要的#xff0c;我们通常需要将对数据库的访问集中起来#xff0c;以保证良好的封装性和可维护性。在.Net中#xff0c;数据库的访问#xff0c;对于微软自家的SqlServer和其他数据库#xff08;支持OleDb#xff09;…在应用程序的设计中数据库的访问是非常重要的我们通常需要将对数据库的访问集中起来以保证良好的封装性和可维护性。在.Net中数据库的访问对于微软自家的SqlServer和其他数据库支持OleDb采用不同的访问方法这些类分别分布于System.Data.SqlClient和System.Data.OleDb名称空间中。微软后来又推出了专门用于访问Oracle数据库的类库。我们希望在编写应用系统的时候不因这么多类的不同而受到影响能够尽量做到数据库无关当后台数据库发生变更的时候不需要更改客户端的代码。 有的时候为了性能和其他原因我们也希望提供对数据库访问的缓存特别是数据库连接的缓存。虽然微软给我们内置了数据库缓存但是自己控制缓存无疑可以提供更大的灵活性和效率。 这就需要我们在实际开发过程中将这些数据库访问类再作一次封装。这里介绍一种在实际应用中得到了非常好的效果的实作策略。Factory和Silgleton设计模式是使用的主要方法。 我们先来看看Factory的含义定义一个用于创建对象的接口让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。我们这里可能会处理对多种数据库的操作因此需要首先定义一个操纵数据库的接口然后根据数据库的不同由类工厂决定实例化哪个类。 下面我们首先来定义这个访问接口。为了方便说明问题我们为这个类定义了比较少的方法其他的方法是很容易参照添加的。同时注意我这里使用了abstract class来定义这个访问接口而不是interface理由在后面可以看到。 public abstract class DBOperator { 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(); //回滚一个事务 public abstract void exeSql(string strSql,string[] strParams,object[] objValues); //执行Sql语句没有返回值 public abstract DataSet exeSqlForDataSet(string QueryString);//执行Sql返回DataSet } 然后我们分别为Sql Server和OleDb数据库编写两个数据访问的具体实现类 Sql Server的数据库访问类 internal class SqlDBOperator: DBOperator { private SqlConnection conn; //数据库连接 private SqlTransaction trans; //事务处理类 private bool inTransactionfalse; //指示当前是否正处于事务中 public override IDbConnection Connection { get{return this.conn;} } public SqlDBOperator(string strConnection) { this.conn new SqlConnection(strConnection); } public override void Open() { if(conn.State.ToString().ToUpper()!OPEN) this.conn.Open(); } public override void Close() { if (conn.State.ToString().ToUpper()OPEN) this.conn.Close(); } public override void BeginTrans() { transconn.BeginTransaction() ; inTransactiontrue; } public override void CommitTrans() { trans.Commit(); inTransactionfalse; } public override void RollbackTrans() { trans.Rollback(); inTransactionfalse; } public override void exeSql(string strSql,string[] strParams,object[] strValues) { SqlCommand cmdnew SqlCommand(); cmd.Connectionthis.conn ; if(inTransaction) cmd.Transactiontrans; if((strParams!null)(strParams.Length!strValues.Length) ) throw new ParamValueNotMatchException(查询参数和值不对应!); cmd.CommandTextstrSql; if(strParams!null) { for(int i0;istrParams.Length;i) cmd.Parameters.Add(strParams[i],strValues[i]); } cmd.ExecuteNonQuery(); } public override DataSet exeSqlForDataSet(string QueryString) { SqlCommand cmdnew SqlCommand(); cmd.Connectionthis.conn ; if(inTransaction) cmd.Transactiontrans; DataSet ds new DataSet(); SqlDataAdapter ad new SqlDataAdapter(); cmd.CommandTextQueryString; ad.SelectCommand cmd; ad.Fill(ds); return ds; } } OleDb数据库操作的类同Sql Server数据库操作的类非常相似只是把相应的Sql类替换成OleDb类。需要注意的是因为OleDb和Sql Server的参数传递方式不一致所以这里需要做一点小小的转换将参数名类型的参数转换成这个细节希望读者能够注意到。代码如下 internal class OleDBOperator : DBOperator { private OleDbConnection conn; private OleDbTransaction trans; private bool inTransactionfalse; public OleDBOperator(string strConnection) { this.conn new OleDbConnection(strConnection); } public override IDbConnection Connection { get{return this.conn;} } public override void Open() { if(conn.State.ToString().ToUpper()!OPEN) this.conn.Open(); } public override void Close() { if (conn.State.ToString().ToUpper()OPEN) this.conn.Close(); } public override void BeginTrans() { transconn.BeginTransaction() ; inTransactiontrue; } public override void CommitTrans() { trans.Commit(); inTransactionfalse; } public override void RollbackTrans() { trans.Rollback(); inTransactionfalse; } public override void exeSql(string strSql,string[] strParams,object[] strValues) { OleDbCommand cmdnew OleDbCommand(); cmd.Connectionthis.conn ; if(inTransaction) cmd.Transactiontrans; if((strParams!null)(strParams.Length!strValues.Length) ) throw new ParamValueNotMatchException(查询参数和值不对应!); cmd.CommandTextthis.ChangeQueryString(strSql); if(strParams!null) { for(int i0;istrParams.Length;i) cmd.Parameters.Add(strParams[i],strValues[i]); } cmd.ExecuteNonQuery(); } public override DataSet exeSqlForDataSet(string QueryString) { OleDbCommand cmdnew OleDbCommand(); cmd.Connectionthis.conn ; if(inTransaction) cmd.Transactiontrans; DataSet ds new DataSet(); OleDbDataAdapter ad new OleDbDataAdapter(); cmd.CommandTextQueryString; ad.SelectCommand cmd; ad.Fill(ds); return ds; } } 现在我们已经完成了所要的功能下面我们需要创建一个Factory类来实现自动数据库切换的管理。这个类很简单主要的功能就是根据数据库连接字符串判断使用什么数据库然后返回适当的数据库操纵类。在这里判断的方法很简单只是根据两种数据库连接字符串的不同来判断。在实际中随着数据库类的增加判断的方法可能会有所变化读者应当根据自己的实际情况来做相应的调整。 public class DBOperatorFactory { public static DBOperator GetDBOperator(string strConnection) { if(strConnection.IndexOf(provider)0) //SqlServer { return new SqlDBOperator(strConnection); } else //other database { return new OleDBOperator(strConnection); } } } 好了现在一切都完成了客户端在代码调用的时候可能就是采用如下形式 DBOperator dbDBOperatorFactory.GetDBOperator(strConnection) db.Open(); db.需要的操作 db.Close(); 或者 DBOperator dbDBOperatorFactory.GetDBOperator(strConnection) db.Open();db.BeginTrans(); try { db.需要的操作 db.CommitTrans(); } catch { db.RollbackTrans(); } db.Close(); 当数据库发生变化的时候DBOperatorFactory会根据数据库连接字符串自动调用相应的类客户端不会感觉到变化也不用去关心。这样实现了良好的封装性。当然前提是你在编写程序的时候没有用到特定数据库的特性例如Sql Server的专用函数。 实际上Factory模式也可以不使用Factory类来实现而是让接口抽象类自己来管理这可以称作自管理的Factory是Factory模式的一种变形。这么做的好处是可以免去一个Factory类使代码更加简练。这么做我们需要对DBOperator类做一些改变增加一个Instance方法。这也是对DBOperator采用抽象类而不是接口的原因接口的方法不能有实现代码如下 public static DBOperator Instance(string strConnection) { if(strConnection.IndexOf(provider)0) //SqlServer { return new SqlDBOperator(strConnection); } else //other database { return new OleDBOperator(strConnection); } } 然后客户端代码就可能是类似于下面的形式 DBOperator db DBOperator.Instance(strConnection) db.Open(); db.需要的操作 db.Close(); 下面来看看连接池的做法方法就是Singleton。 先看Singleton模式的经典含义保证一个类仅有一个实例并提供一个访问它的全局访问点。推而广之当我们需要精确控制类在系统中的实例的个数的时候就可以使用Singleton模式。现在我们需要构建一个缓冲池保存数据库类的实例正好是Singleton模式发挥作用的时候。 我们仍然让DBOperator类自己来管理这个缓冲池为了实现这个目的我们需要对DBOperator类做一些变化 首先增加两个变量 static DBOperator[] ConnectionPoolnew DBOperator[int.Parse(ConfigurationSettings.AppSettings[PoolCount])]; static int CurrentPosition-1; 然后对Instance方法做一些改变 public static DBOperator Instance(string strConnection) { if(ApplicationConfiguration.PooledConnectionCount1) //没有缓冲 { return CreateNewDBOperator(strConnection); } else { CurrentPosition; if(CurrentPositionApplicationConfiguration.PooledConnectionCount) CurrentPosition0; if(ConnectionPool[CurrentPosition]null) { ConnectionPool[CurrentPosition]CreateNewDBOperator(strConnection); } return ConnectionPool[CurrentPosition]; } } private static DBOperator CreateNewDBOperator(string strConnection) { if(strConnection.IndexOf(provider)0) //SqlServer { return new SqlDBOperator(strConnection); } else //other database { return new OleDBOperator(strConnection); } } 这里使用的算法比较简单只是为了能够比较清楚地说明问题读者应当能够在实际使用过程中实现更好的算法。 以上介绍了一种通用数据库操作类的实现设计方法希望能够对大家有所启发。笔者设计Websharp中间件的时候在数据库处理层采用了上面的方法取得了很好的效果。