** 自建工具集开发文档 ** ** ------ ** ** 数据库操作( ** ** 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();
<SPAN s