自建工具集开发文档------数据库操作(1.0.0.1)

类别:.NET开发 点击:0 评论:0 推荐:

自建工具集开发文档------数据库操作(1.0.0.1

 

 

版本号

创建人

创建时间

备注

1.0.0.1

穆仕途

2003-12-21

草稿

 

 

关键字C#、工具集、数据库、连接池

正文

 

       .Net Framework提供ADO.NET功能强大,在此写这个数据库处理类的主要目的是为了把数据库处理集中处理,自动生成简单的SQL语句,对上层隐藏数据库细节,方便于扩展和维护。并且可以把它放到别的系统中而不需要做程序上的改动,只需要修改部分配置信息而已。

 

设计目标

 

1.     实现数据库连接池,并可配置池的大小,配置是否使用连接池。

2.     自动生成插入、删除、更新的SQL语句。

3.     自动生成简单的查询、聚合查询的SQL语句。

4.     通过配置可以选择为不同数据库实现的操作类集合。

5.     对上层隐藏数据库细节,隐藏数据源细节。

6.     从数据库自动导出数据库结构,并存放于XML文件供程序使用。

 

设计思想:

 

主要思想是:把数据库相关的所有操作全部封装起来,内部的实现采用自动生成SQL语句,对表和列的引用都采用别名,尽量分离各种耦合,用配置文件来减少重用或者修改所来的工作量。比如对表的字段名称的修改将不会影响到工具和系统的变动。

目前只实现了Microsoft SQL Server2000的操作。

 

结构说明:

 

       主要包括一个接口和4个类,他们的关系如下图所示:

 

 

1.       IDBase接口类:定义了一系列数据库操作的公共方法,针对某种数据库或别的数据源写的操作类都必须实现这个借口。

2.       SqlDBase类:实现所有的数据库操作,包括插入、更新、删除、查询、执行存储过程等,实现上面的接口定义的方法。

3.       DbaseFactory类:定义了一个工厂,根据系统配置文件中配置的信息来决定调用那一个数据库操作类,在本系统中,只实现了SQL Server中的数据库操作类,可以扩展至别的数据库操作。使用了工厂(Factory)模式。

4.       DBPool类:实现了数据库连接池,可以从中获取可用的数据库连接,里面使用了单件(Singleton)模式。

5.       ownConnection类:封装了框架提供的SqlConnection对象,增加了一层状态信息,主要供DBPool类使用。

 

下面逐个介绍这些类。

 

ownConnection类:

 

封装了框架提供的SqlConnection对象,主要目的是为连接加入一个自定义的状态。在数据库连接池中将存放多个连接对象,对连接对象的操作将主要参照这里自定义的状态。

 

字段

 

private string _connectionString = Constant.Data_Base_Connection;

private SqlConnection _myConnection = new SqlConnection();

private Constant.ConnectionStatus _status;

 

     _connectionString:数据库连接字符串,用Constant类的常量来构造。

     _myConnection:数据库连接,SqlConnection对象

     _status状态,取值由常量类中的一个枚举型确定,有这几种值Free、Busy、Death

 

方法:

 

private bool OpenConnection()

public ownConnection()

public SqlConnection GetConnection()

public void SetToBusy()

public void ResetConnection()

 

     OpenConnection():私有方法,根据字段connectionString来打开数据库连接,打开失败则抛出异常。

     ownConnection():公共构造函数,在内部调用方法OpenConnection(),设置本实例的状态,打开成功设为Free,否则设为Death。

     GetConnection():获取可用的数据库连接,返回一个SqlConnection对象。

     SetToBusy():把本实例的状态设置为Busy,标志本连接正在使用中。

     ResetConnection():重设数据库连接,如果连接状态无效,则调用OpenConnection()重新打开连接。

 

DBPool

 

        数据库连接池类,使用了Singleton模式来保证实例的唯一性,根据配置文件中设置的连接池的大小,维护一个连接对象数组,给数据库操作类提供可用的数据库连接。

 

字段:

 

private static ArrayList DBPools = new ArrayList(Constant.Init_Pool_Size)

private static int initPoolSize;

private static int validConnectionCount;

private static volatile DBPool instance = new DBPool();

private static object syncRoot = new object();

 

由于DBPool类在系统中只能有一个实例,所以,字段都标记为static。这些字段将长驻内存,并且在系统启动的时候就初始化。

 

     DBPools:存放数据库连接的一个静态数组ArrayList,大小为系统配置文件中定义的连接池大小。

     initPoolSize:连接池大小,值和系统配置文件中定义的池的大小一致。

     validConnectionCount:连接池中可用的连接数,为0时代表没有可用连接,初始为0

     instance:连接池对象,初始化时就实例化,保证了系统启动的时候就实例化连接池对象,这是单件模式的一部分,后面将专门讲述我对这个模式的理解。

     syncRoot:初始化一个同步对象,在单件模式中防止死锁,将在后面讲述。

 

方法:

 

private static bool InitPool()

private DBPool()

public static DBPool Instance

public static ownConnection GetConnection()

public static SqlConnection GetConnection(string conName)

 

     InitPool():根据数据库连接池大小初始化数据库连接池,并且返回初始化成败标志,目前的程序皆返回成功,发生异常的时候将由上层处理。

     DBPool():私有构造器,防止被实例化。设置字段,调用InitPool()初始化连接池。

     Instance:获取数据库连接池的实例。

     GetConnection():获取一个数据库连接。

     GetConnection(string conName):重载上面的方法,这里将根据参数决定是否从连接池中取数据。这样实现的考虑是:可能一个系统会对应几个数据库,而连接池中放的都是基于一个数据库的连接,别的数据库连接将这个重载的方法来获取。

 

Singleton模式的应用,代码如下图:

 

private static volatile DBPool instance = new DBPool();

private static object syncRoot = new object();

 

private DBPool()

{

     try

     {

         initPoolSize = Constant.Init_Pool_Size;

         validConnectionCount = 0;

         InitPool();

     }

     catch(utilException e)

     {

     }

     catch(Exception e)

     {

         utilException myException = new utilException(e, "");

     }

}

 

public static DBPool Instance

{

     get

     {

         if(instance == null)

         {

              lock(syncRoot)

              {

                   if(instance == null)

                       instance = new DBPool();

              }

         }

 

         return instance;

     }

}

 

 

 

静态字段instance的声明,将调用私有构造器,当系统启动的时候,就有了一个数据库连接池对象,当需要使用连接池对象的时候,通过静态属性Instance来访问,主要说明一下这个属性内部的实现。

 

1.       系统启动的时候,就应该存在一个连接池实例,如果不为空则直接返回实例,否则

2.       lock(syncRoot)确保当一个线程位于代码的临界区时,另一个线程不进入临界区,进行互斥的访问,防止同时的请求而生成多个实例。

 

这样就保证了数据库连接池实例的唯一性,也是Singleton模式的典型的应用

 

连接池的维护

 

1.       初始化连接池的时候按连接池大小建立数据库连接;

2.       用户用GetConnection()请求一个连接的时候,在连接池里面遍历数据库连接对象,找到可用的数据库连接后,把连接对象的状态设置为Busy,然后返回连接对象;

3.       当连接池内没有可用的连接时,则遍历数据库连接对象,把所有不可用的连接对象用ResetConnection()来重新打开连接。

4.       继续执行步骤2,返回可用的连接对象;如果仍然没有可用连接返回,执行步骤5

5.       抛出一个异常,说明连接全部被占用。

本文地址:http://com.8s8s.com/it/it45197.htm