数 据 库 连 接

大多数数据库接口依赖于某些数据库连接对象,它们好像应用程序代码和数据库之间的桥梁。通常,一个连接必须在执行数据库操作命令之前就要打开。实际上,经常需要一个显示连接来建立和执行命令。在命令执行的整个过程中,该连接必须是打开的,查询的结果将返回一个记录集,才关闭数据库连接。如果正在一个事务中运行,经常会把事务绑定在特定的连接上,当它运行的时候这个连接也必须一直打开,直到这个事务结束才能关闭连接。

在很多环境中,建立连接的开销相当大,这就需要建立一个连接池。在这种情况下,开发者向连接池请求一个连接并在完成以后释放,而无需即时创建和关闭。注意这里不是要你自己去创建连接池,因为现在多数平台都会提供连接池,所以很少需要自己来实现连接池。如果必须自己实现连接池,首先就要检查连接池是不是真的能提高性能(对连接池的创建可以参考后面的代码【1】)。还要注意:越来越多的环境使我们可以更快地创建新的连接,因此也不需要使用缓冲池。

提供连接池的环境把连接池放在一个类似创建新连接的接口后面。用这种方法,无需知道得到得是一个新创建连接还是从连接池里面分配的。类似地,关闭一个连接可能并没有真正关闭它,而只是把它替换为从连接池获取和释放。

无论创建连接的代价是高还是低,连接都必须好好管理,因为它们是珍贵的资源,必须在使用完毕时立刻关闭。还有,如果正在进行一次事务,通常需要保证:在这次特定的事务中,每一个命令都是从同一个连接发出的。

       最常见的建议就是用一个到连接池或者连接管理器的调用,显示得到一个连接,并且通过它来执行数据库命令,一旦执行完了,立刻把它关闭。这个建议带来两个问题:首先,保证在任何需要的地方都能得到一个连接;其次,保证不会在最后忘记关闭它(可以参考后面得示例代码【2】)。

       现代环境提供了自动的内存管理和垃圾回收机制,因此保证连接关闭的一种方法就是使用垃圾回收器。在这种方式下,连接自身或者引用这个连接的对象会在垃圾回收期间关闭连接。这样做的好处是:它使用了和内存管理相同的机制,同样方便,也不陌生。这样做的问题是:连接的关闭只有当垃圾回收器实际回收内存的时候才发生,可能离这个连接失去它最后一次引用的时间已经很久了,结果是未被引用的连接可能会隔一段时间才被关闭。总的来说,我不喜欢依赖垃圾回收机制,对于其它的机制,甚至是显示关闭都会好一些。当然,垃圾回收机制在其它机制失败的情况下还是一种很好的后备。

       连接管理细节描述的往往是数据库交互软件的特征,因此所使用的策略通常是由环境来决定的。

 

 

 

连接池的创建示例代码【1】:

using System;

using System.Timers;

using System.Collections;

using System.Data.SqlClient;

using Common;

 

 

 

namespace SqlDBConnection

{

     /// <summary>

     /// DBConnection 的数据库连接对象池。

     /// </summary>

     public sealed class DBConnection:ObjectPool

     {

         private DBConnection()

         {

             

         }

 

 

 

         public static readonly DBConnection Instance=new DBConnection();

 

 

 

        

 

 

 

         private static  string _connectionstring="数据库连接字符串";

             

 

 

 

         public static string Connectionstring

         {

              set

              {

                   _connectionstring=value;

              }

              get

              {

                   return _connectionstring;

              }

         }

 

 

 

         protected override object Create()

         {

              try

              {

                   SqlConnection temp=new SqlConnection(_connectionstring);

                   temp.Open();

                   return(temp);

              }

              catch

              {

                   return null;

              }

         }

 

 

 

         protected override bool Validate(object o)

         {

              try

              {

                   SqlConnection temp=(SqlConnection)o;

                   return(!((temp.State.Equals(System.Data.ConnectionState.Closed))));

              }

              catch(SqlException)

              {

                   return false;

              }

         }

 

 

 

         protected override void Expire(object o)

         {

              try

              {

                   ((SqlConnection)o).Close();

              }

              catch(SqlException)

              {

              }

         }

 

 

 

         public SqlConnection BorrowDBConnection()

         {

              try

              {

                   return((SqlConnection)base.GetObjectFromPool());

              }

              catch(Exception e)

              {

                   throw e;

              }

         }

 

 

 

         public void ReturnDBConnection(SqlConnection c)

         {            

              base.ReturnObjectToPool(c);

         }

     }

 

 

 

 

 

 

     /// <summary>

     /// ObjectPool 的对象池。

     /// </summary>

     public abstract class ObjectPool

     {

         private long _lastCheckOut;

         private static Hashtable locked;

         private static Hashtable unlocked;

         internal static  long CARBAGE_INTERVAL=9*1000;

 

 

 

         static ObjectPool()

         {

              locked=Hashtable.Synchronized(new Hashtable());

              unlocked=Hashtable.Synchronized(new Hashtable());

         }

 

 

 

         internal ObjectPool()

         {

              _lastCheckOut=DateTime.Now.Ticks;

              System.Timers.Timer aTimer=new System.Timers.Timer();

              aTimer.Enabled=true;

              aTimer.Interval=CARBAGE_INTERVAL;

              aTimer.Elapsed+=new System.Timers.ElapsedEventHandler(CollectGarbage);

         }

 

 

 

         protected abstract object Create();

 

 

 

         protected abstract bool Validate(object o);

 

 

 

         protected abstract void Expire(object o);

 

 

 

         internal object GetObjectFromPool()

         {

              long now=DateTime.Now.Ticks;

              _lastCheckOut=now;

              object o=null;             

              o=Create();

              locked.Add(o,now);              

             

              return(o);            

         }

 

 

 

         internal void ReturnObjectToPool(object o)

         {

              if(o!=null)

              {

                   lock(this)

                   {

                       locked.Remove(o);

                       unlocked.Add(o,DateTime.Now.Ticks);

                   }

              }

         }

 

 

 

         private void CollectGarbage(object sender,System.Timers.ElapsedEventArgs ea)

         {

              lock(this)

              {

                   object o;

                   long now=DateTime.Now.Ticks;

                   IDictionaryEnumerator e=unlocked.GetEnumerator();

 

 

 

                   try

                   {

                       while(e.MoveNext())

                       {

                            o=e.Key;

                            if((now-((long)unlocked[o]))>CARBAGE_INTERVAL)

                            {

                                 unlocked.Remove(o);

                                 Expire(o);

                                 o=null;

                            }

                       }

                   }

                   catch(Exception){}

              }

         }

     }

}

 

 

 

 

 

 

数据库连接示例代码【2:

 

 

 

using System;

using System.Data;

using System.Data.SqlClient;

using System.Configuration;

using SqlDBConnection;

using Common;

 

 

 

namespace MyMedia_Competitor

{

     /// <summary>

     /// SqlDataBase 的摘要说明。

     /// </summary>

     public class MySqlDataBase

     {

         /// <summary>

         /// 构造函数

         /// </summary>

         public MySqlDataBase()

         {

             

         }   

         public DBConnection Connection; 

 

 

 

         /// <summary>

         /// 获取数据库连接接口

         /// </summary>

         public IDbConnection GetConnection()

         {

              IDbConnection sqlConnection1 = null;

              string connectionstring="数据库连接字符串";   

              sqlConnection1=(IDbConnection)new SqlConnection(connectionstring);

              sqlConnection1.Open();

              return sqlConnection1;

         }

 

 

 

         /// <summary>

         /// 将数据库连接接口返回连接池

         /// </summary>

         public void ReturnConnection(SqlConnection obj)

         {            

              Connection.ReturnDBConnection(obj);

         }

 

 

 

         /// <summary>

         /// 根据数据库类型获取数据库命令接口

         /// </summary>

         /// <param name="sqlstr">数据库命令字符串</param>

         /// <param name="sqlConnection1">数据库连接接口</param>

         /// <returns>数据库命令接口</returns>

         /// </summary>

         private IDbCommand GetCommand(string sqlstr, IDbConnection sqlConnection1)

         {

              IDbCommand sqlCommand1 = null;           

              sqlCommand1 = new SqlCommand(sqlstr,(SqlConnection)sqlConnection1);

              sqlCommand1.CommandTimeout=99999999;

              return sqlCommand1;

         }

 

 

 

         /// <summary>

         /// 根据数据库类型获取数据适配器接口     

         /// <param name="sqlCommand1">数据库命令接口</param>

         /// <returns>数据适配器接口</returns>

         private IDataAdapter GetDataAdapter(IDbCommand sqlCommand1)

         {

              IDataAdapter sqlDataAdapter1 = null;

              sqlDataAdapter1 = new SqlDataAdapter((SqlCommand)sqlCommand1);

              DataAdapte=sqlDataAdapter1;

              return sqlDataAdapter1;

         }

 

 

 

         /// <summary>

         /// 数据适配器属性

         /// </summary>

         IDataAdapter DataAdapte=null;

         private IDataAdapter DataAdapter

         {            

              get

              {                 

                   return DataAdapte;

              }

         }

 

 

 

         /// <summary>

         /// 下面是处理数据,返回结果集

         /// </summary>

// 1.

         /// <summary>

         /// 执行SQL语句并返回受影响的行的数目    

         /// <param name="sqlstr">数据库命令字符串</param>

         /// <returns>受影响的行的数目</returns>

         /// </summary>

         public int ExecuteNonQuery(string sqlstr)

         {

              IDbConnection sqlConnection1 = null;

              IDbCommand sqlCommand1 = null;

              try

              {

                   sqlConnection1 = this.GetConnection();

                   sqlCommand1 = this.GetCommand(sqlstr, sqlConnection1);

                   return sqlCommand1.ExecuteNonQuery();

              }

              catch (Exception ex)

              {

                   System.Diagnostics.Debug.WriteLine(ex.Message);

                   return 0;

              }

              finally

              {

                   if (sqlCommand1 != null)

                       sqlCommand1.Dispose();

                   if (sqlConnection1 != null)

                       sqlConnection1.Close();

                   //   Connection.ReturnDBConnection((SqlConnection)sqlConnection1);

              }

         }

// 2.

         /// <summary>

         /// 执行SQL语句并返回数据行     

         /// <param name="sqlstr">数据库命令字符串</param>

         /// <returns>数据读取器接口</returns>

         /// </summary>

         public SqlDataReader ExecuteReader(string sqlstr)

         {

              IDbConnection sqlConnection1 = null;

              IDbCommand sqlCommand1 = null;

 

 

 

              try

              {

                   sqlConnection1 = this.GetConnection();

                   sqlCommand1 = this.GetCommand(sqlstr, sqlConnection1);

                   return (SqlDataReader)sqlCommand1.ExecuteReader(CommandBehavior.CloseConnection);

              }

              catch (Exception ex)

              {

                   System.Diagnostics.Debug.WriteLine(ex.Message);

                   return null;

              }

              finally

              {

                   if (sqlCommand1 != null)

                       sqlCommand1.Dispose();

                   if (sqlConnection1 != null)

                       sqlConnection1.Close();

                   //   Connection.ReturnDBConnection((SqlConnection)sqlConnection1);

              }

         }

// 3.

         /// <summary>

         /// 执行SQL语句并返回单值对象

         /// 即结果集中第一行的第一条数据    

         /// <param name="sqlstr">数据库命令字符串</param>

         /// <returns>单值对象-结果集中第一行的第一条数据</returns>

         /// </summary>

         public object ExecuteScalar(string sqlstr)

         {

              IDbConnection sqlConnection1 = null;

              IDbCommand sqlCommand1 = null;

 

 

 

              try

              {

                   sqlConnection1 = this.GetConnection();

                   sqlCommand1 = this.GetCommand(sqlstr, sqlConnection1);

 

 

 

                   return sqlCommand1.ExecuteScalar();

              }

              catch (Exception ex)

              {

                   System.Diagnostics.Debug.WriteLine(ex.Message);

                   return null;

              }

              finally

              {

                   if (sqlCommand1 != null)

                       sqlCommand1.Dispose();

                   if (sqlConnection1 != null)

                       sqlConnection1.Close();

                   //   Connection.ReturnDBConnection((SqlConnection)sqlConnection1);

              }

         }

// 4.

         /// <summary>

         /// 填充一个数据集对象并返回之      

         /// <param name="sqlstr">数据库命令字符串</param>

         /// <returns>数据集对象</returns>

         /// </summary>

         public DataSet GetDataSet(string sqlstr)

         {

              IDbConnection sqlConnection1 = null;

              IDbCommand sqlCommand1 = null;

              IDataAdapter sqlDataAdapter1 = null;

              DataSet ds = null;

 

 

 

              try

              {

                   sqlConnection1 = this.GetConnection();

                   sqlCommand1 = this.GetCommand(sqlstr, sqlConnection1);

                   sqlDataAdapter1 = this.GetDataAdapter(sqlCommand1);

 

 

 

                   ds = new DataSet();

                   sqlDataAdapter1.Fill(ds);

                   return ds;

              }

              catch (Exception ex)

              {

                   System.Diagnostics.Debug.WriteLine(ex.Message);

                   return null;

              }

              finally

              {

                   if (sqlCommand1 != null)

                       sqlCommand1.Dispose();

                   if (sqlConnection1 != null)

                       sqlConnection1.Close();

                       //Connection.ReturnDBConnection((SqlConnection)sqlConnection1);

              }

         }

// 5.

         /// <summary>

         /// 执行存储过程      

         /// <param name="StoredStr">存储过程名</param>

         /// <param name="arrParams">所要传入的参数</param>

         /// <returns>数据集对象</returns>

         /// </summary>

         public DataSet GetDataSetForStored(string StoredStr,SqlParameter[] arrParams)

         {

              IDbConnection sqlConnection1 = null;

              IDbCommand sqlCommand1 = null;

              IDataAdapter sqlDataAdapter1 = null;

              DataSet ds=null;

              try

              {

                   sqlConnection1 = this.GetConnection();

                   sqlCommand1 = this.GetCommand(StoredStr, sqlConnection1);

                   sqlCommand1.CommandType=CommandType.StoredProcedure;

                   for(int i=0;i<arrParams.Length;i++)

                   {                      

                       sqlCommand1.Parameters.Add(arrParams[i]);                       

                   }

                   sqlDataAdapter1 = this.GetDataAdapter(sqlCommand1);

                   ds=new DataSet();

                   sqlDataAdapter1.Fill(ds);

                   return ds;

              }

              catch (Exception ex)

              {

                   System.Diagnostics.Debug.WriteLine(ex.Message);

                   return null;

              }

              finally

              {

                   if (sqlCommand1 != null)

                       sqlCommand1.Dispose();

                   if (sqlConnection1 != null)

                       sqlConnection1.Close();

                   //   Connection.ReturnDBConnection((SqlConnection)sqlConnection1);

              }            

         }

// 6.

         /// <summary>

         /// 执行存储过程      

         /// <param name="StoredStr">存储过程名</param>

         /// <param name="arrParams">所要传入的参数</param>

         /// <returns>数据集对象</returns>

         /// </summary>

         public void RunStored(string StoredStr,SqlParameter[] arrParams)

         {

              IDbConnection sqlConnection1 = null;

              IDbCommand sqlCommand1 = null;

              try

              {

                   sqlConnection1 = this.GetConnection();

                   sqlCommand1 = this.GetCommand(StoredStr, sqlConnection1);

                   sqlCommand1.CommandType=CommandType.StoredProcedure;

                   for(int i=0;i<arrParams.Length;i++)

                   {                     

                       sqlCommand1.Parameters.Add(arrParams[i]);                       

                   }

                   sqlCommand1.ExecuteNonQuery();

              }

              catch (Exception ex)

              {

                   System.Diagnostics.Debug.WriteLine(ex.Message);

              }

              finally

              {

                   if (sqlCommand1 != null)

                       sqlCommand1.Dispose();

                   if (sqlConnection1 != null)

                       sqlConnection1.Close();

                       //Connection.ReturnDBConnection((SqlConnection)sqlConnection1);

              }            

         }

 

 

 

         /// <summary>

         /// 还可以继续扩张

         /// </summary>

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值