我从学习Asp.Net(C#)开始到将其作为谋生工具至今已18月有余,当初有那么一阵对.NET的CLR很似痴迷,对C#2.0所带来
的新特性也疯狂不已。因为工作环境所迫,已经很久没有使用VS2005/2008作为自己的IDE了,一直在VS2003中煎熬的感觉已
经让我失去了对痛苦的理解,或许这也是逼迫我逐步转向前端开发的一个原动力吧。
这个“数据库访问层”的诞生是在我接触.NET和SQL Sever半年之后,在“师傅”的指点下通过硬背下代码,再到后来逐步
加深对其实质的理解,能够按照师傅的要求在18分钟准确无误的书写下每一行代码,那时所获得满足感,或许只有曾经有过类似
经历的“战友”们才能体味。
该“数据库访问层”还有许多不太完善的地方,例如缺少事务的处理(对于现在我的来说,一般喜欢放在存储过程来完成)等,
希望下列代码对大家有所帮助:
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
namespace DBAccessLayer
{
#region 数据库访问接口
/// <summary>
/// 名称: IDBAccess
/// 功能: 数据库访问接口
/// 作者: 张 亮
/// 版本: V1.0
/// 时间: 2008年5月14日
/// 修改人:
/// 修改时间:
/// 修改描述:
/// </summary>
public interface IDBAccess
{
#region 打开数据库连接的方法
/// <summary>
/// 打开数据库连接的方法
/// </summary>
bool OpenConnection();
#endregion
#region 关闭数据库连接的方法
/// <summary>
/// 关闭数据库连接的方法
/// </summary>
bool CloseConnection();
#endregion
#region 执行一条T_SQL命令返回影响的行数的方法(适合执行Update、Delete、Insert三种T_SQL语句)
/// <summary>
/// 执行一条T_SQL命令返回影响的行数的方法(适合执行Update、Delete、Insert三种T_SQL语句)
/// </summary>
/// <param name="CommandText">T_SQL命令字符串或存储过程名</param>
/// <param name="type">T_SQL命令的类型(文本类型:Text或存储过程类型:StoredProcedure)</param>
/// <param name="paraList">T_SQL命令的参数集合(无参数添加时即为null)</param>
/// <returns>返回影响的行数(row)</returns>
int ExecuteNonQuery(string commandText, CommandType type, IDataParameter[] paraList);
#endregion
#region 执行一条T_SQL命令返回首行首列的方法(适合执行Select命令中含有聚合函数的T_SQL语句)
/// <summary>
/// 执行一条T_SQL命令返回首行首列的方法(适合执行Select命令中含有聚合函数的T_SQL语句)
/// </summary>
/// <param name="selectcommandText">T_SQL命令字符串或存储过程名</param>
/// <param name="type">T_SQL命令的类型(文本类型:Text或存储过程类型:StoredProcedure)</param>
/// <param name="paraList">T_SQL命令的参数集合(无参数添加时即为null)</param>
/// <returns>返回首行首列(obj)</returns>
object ExecuteScalar(string selectcommandText, CommandType type, IDataParameter[] paraList);
#endregion
#region 执行一条T_SQL命令返回IDataReader的方法(适合连接模式执行Select命令的T_SQL语句)
/// <summary>
/// 执行一条T_SQL命令返回IDataReader的方法(适合连接模式执行Select命令的T_SQL语句)
/// </summary>
/// <param name="selectcommandText">T_SQL命令字符串或存储过程名</param>
/// <param name="type">T_SQL命令的类型(文本类型:Text或存储过程类型:StoredProcedure)</param>
/// <param name="paraList">T_SQL命令的参数集合(无参数添加时即为null)</param>
/// <returns>返回数据读取器(reader)</returns>
IDataReader ExecuteReader(string selectcommandText, CommandType type, IDataParameter[] paraList);
#endregion
#region 执行一条T_SQL命令返回DataSet的方法(适合断开模式执行Select命令的T_SQL语句)
/// <summary>
/// 执行一条T_SQL命令返回DataSet的方法(适合断开模式执行Select命令的T_SQL语句)
/// </summary>
/// <param name="selectcommandText">T_SQL命令字符串或存储过程名</param>
/// <param name="type">T_SQL命令的类型(文本类型:Text或存储过程类型:StoredProcedure)</param>
/// <param name="paraList">T_SQL命令的参数集合(无参数添加时即为null)</param>
/// <returns>返回数据记录集(ds)</returns>
DataSet ExecuteDataSet(string selectcommandText, CommandType type, IDataParameter[] paraList);
#endregion
}
#endregion
}
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
namespace DBAccessLayer
{
#region 数据库访问类(从IDBAccess接口派生出来)
/// <summary>
/// 名称: DBAccess<Connection, Command, DataAdapter>
/// 功能: 数据库访问类(从IDBAccess接口派生出来)
/// 作者: 张 亮
/// 版本: V1.0
/// 时间: 2008年5月14日
/// 修改人:
/// 修改时间:
/// 修改描述:
/// </summary>
/// <typeparam name="Connection">数据库连接数据类型</typeparam>
/// <typeparam name="Command">数据库命令数据类型</typeparam>
/// <typeparam name="DataAdapter">数据库数据适配器数据类型</typeparam>
class DBAccess<Connection, Command, DataAdapter> : IDBAccess
where Connection : IDbConnection, new()
where Command : IDbCommand, new()
where DataAdapter : IDbDataAdapter, new()
{
#region 连接字符串字段
/// <summary>
/// 连接字符串字段
/// </summary>
private Connection conn;
#endregion
#region 连接字符串的有参构造方法
/// <summary>
/// 连接字符串的有参构造方法
/// </summary>
/// <param name="connectionString">指定的连接字符串</param>
public DBAccess(string connectionString)
{
this.conn = new Connection();
this.conn.ConnectionString = connectionString;
}
#endregion
#region IDBAccess 成员
#region 打开数据库连接的方法
/// <summary>
/// 打开数据库连接的方法
/// </summary>
/// <returns>bIsSucceed(true:打开数据库连接成功 false:打开数据库连接失败)</returns>
public bool OpenConnection()
{
bool bIsSucceed = true;
try
{
// 判断数据库连接是否打开,没有打开则打开数据库
if (this.conn.State != ConnectionState.Open)
{
this.conn.Open();
}
}
catch (Exception exp)
{
bIsSucceed = false;
throw new Exception("打开数据库连接错误! 信息:" + exp.Message);
}
return bIsSucceed;
}
#endregion
#region 关闭数据库连接的方法
/// <summary>
/// 关闭数据库连接的方法
/// </summary>
/// <returns>bIsSucceed(true:关闭数据库连接成功 false:关闭数据库连接失败)</returns>
public bool CloseConnection()
{
bool bIsSucceed = true;
try
{ // 判断数据库连接是否关闭,没有关闭则关闭数据库
if (this.conn.State != ConnectionState.Closed)
{
this.conn.Close();
}
}
catch (Exception exp)
{
bIsSucceed = false;
throw new Exception("关闭数据库连接错误! 信息:" + exp.Message);
}
return bIsSucceed;
}
#endregion
#region 创建一个Command对象的方法(指定其CommandText, CommandType, Connection,有参数则添加参数)
/// <summary>
/// 创建一个Command对象的方法(指定其CommandText, CommandType, Connection,有参数则添加参数)
/// </summary>
/// <param name="CommandText">T_SQL命令字符串或存储过程名</param>
/// <param name="type">T_SQL命令的类型(文本类型:Text或存储过程类型:StoredProcedure)</param>
/// <param name="paraList">T_SQL命令的参数集合(无参数添加时即为null)</param>
/// <returns>返回命令对象(cmd)</returns>
private Command CreateCommand(string commandText, CommandType type, IDataParameter[] paraList)
{
Command cmd = new Command();
cmd.CommandText = commandText;
cmd.CommandType = type;
cmd.Connection = this.conn;
// 有参数则添加参数
if (paraList != null)
{
foreach (IDataParameter para in paraList)
{
cmd.Parameters.Add(para);
}
}
return cmd;
}
#endregion
#region 执行一条T_SQL命令返回影响的行数的方法(适合执行Update、Delete、Insert三种T_SQL语句)
/// <summary>
/// 执行一条T_SQL命令返回影响的行数的方法(适合执行Update、Delete、Insert三种T_SQL语句)
/// </summary>
/// <param name="CommandText">T_SQL命令字符串或存储过程名</param>
/// <param name="type">T_SQL命令的类型(文本类型:Text或存储过程类型:StoredProcedure)</param>
/// <param name="paraList">T_SQL命令的参数集合(无参数添加时即为null)</param>
/// <returns>返回影响的行数(row)</returns>
public int ExecuteNonQuery(string commandText, CommandType type, IDataParameter[] paraList)
{
int row = -1;
try
{
// 1.创建一个Command对象,指定其commandText, CommandType, Connection,有参数则添加参数
Command cmd = CreateCommand(commandText, type, paraList);
// 2.打开数据库连接
this.OpenConnection();
// 3.执行命令
row = cmd.ExecuteNonQuery();
}
catch (Exception exp)
{
throw new Exception("执行T_SQL命令返回影响的行数错误! 信息:" + exp.Message);
}
finally
{
// 4.关闭数据库连接
this.CloseConnection();
}
/*
* 另一种写法,可以将 return row; 放在try语句块的末尾.
* finally 程序块成功执行后,然后在执行 return 语句.
*/
// 5.返回影响的行数
return row;
}
#endregion
#region 执行一条T_SQL命令返回首行首列的方法(适合执行Select命令中含有聚合函数的T_SQL语句)
/// <summary>
/// 执行一条T_SQL命令返回首行首列的方法(适合执行Select命令中含有聚合函数的T_SQL语句)
/// </summary>
/// <param name="selectcommandText">T_SQL命令字符串或存储过程名</param>
/// <param name="type">T_SQL命令的类型(文本类型:Text或存储过程类型:StoredProcedure)</param>
/// <param name="paraList">T_SQL命令的参数集合(无参数添加时即为null)</param>
/// <returns>返回首行首列(result)</returns>
public object ExecuteScalar(string selectcommandText, CommandType type, IDataParameter[] paraList)
{
object result = null;
try
{
// 1.创建一个Command对象,指定其commandText, CommandType, Connection,有参数则添加参数
Command cmd = CreateCommand(selectcommandText, type, paraList);
// 2.打开数据库连接
this.OpenConnection();
// 3.执行命令
result = cmd.ExecuteScalar();
}
catch (Exception exp)
{
throw new Exception("执行T_SQL命令返回首行首列错误! 信息:" + exp.Message);
}
finally
{
// 4.关闭数据库连接
this.CloseConnection();
}
// 5.返回首行首列
return result;
}
#endregion
#region 执行一条T_SQL命令返回IDataReader的方法(适合连接模式执行Select命令的T_SQL语句)
/// <summary>
/// 执行一条T_SQL命令返回IDataReader的方法(适合连接模式执行Select命令的T_SQL语句)
/// </summary>
/// <param name="selectcommandText">T_SQL命令字符串或存储过程名</param>
/// <param name="type">T_SQL命令的类型(文本类型:Text或存储过程类型:StoredProcedure)</param>
/// <param name="paraList">T_SQL命令的参数集合(无参数添加时即为null)</param>
/// <returns>返回数据读取器(reader)</returns>
public IDataReader ExecuteReader(string selectcommandText, CommandType type, IDataParameter[] paraList)
{
IDataReader reader = null;
try
{
// 1.创建一个Command对象,指定其commandText, CommandType, Connection,有参数则添加参数
Command cmd = CreateCommand(selectcommandText, type, paraList);
// 2.打开数据库连接
this.OpenConnection();
// 3.执行命令
reader = cmd.ExecuteReader();
}
catch (Exception exp)
{
// 如果出现异常,在连接模式情况下应该先关闭数据库,在抛出异常
this.CloseConnection();
throw new Exception("执行T_SQL命令返回DataReader错误! 信息:" + exp.Message);
}
finally
{
// 4.关闭数据库连接
this.CloseConnection();
}
// 5.返回数据读取器
return reader;
}
#endregion
#region 执行一条T_SQL命令返回DataSet的方法(适合断开模式执行Select命令的T_SQL语句)
/// <summary>
/// 执行一条T_SQL命令返回DataSet的方法(适合断开模式执行Select命令的T_SQL语句)
/// </summary>
/// <param name="selectcommandText">T_SQL命令字符串或存储过程名</param>
/// <param name="type">T_SQL命令的类型(文本类型:Text或存储过程类型:StoredProcedure)</param>
/// <param name="paraList">T_SQL命令的参数集合(无参数添加时即为null)</param>
/// <returns>返回数据记录集(ds)</returns>
public DataSet ExecuteDataSet(string selectcommandText, CommandType type, IDataParameter[] paraList)
{
DataSet data = new DataSet();
try
{
// 1.创建一个Command对象,指定其commandText, CommandType, Connection,有参数则添加参数
Command cmd = CreateCommand(selectcommandText, type, paraList);
// 2.创建一个数据适配器
DataAdapter adapter = new DataAdapter();
adapter.SelectCommand = cmd;
// DataAdapter da = new DataAdapter(cmd);等价于上面的两行代码
// 3.利用数据适配器填充数据记录集
adapter.Fill(data);
}
catch (Exception exp)
{
throw new Exception("执行T_SQL命令返回DataSet错误! 信息:" + exp.Message);
}
finally
{
// 4.关闭数据库连接
this.CloseConnection();
}
// 5.返回数据记录集
return data;
}
#endregion
#endregion
}
#endregion
}
![ContractedBlock.gif](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
![ExpandedBlockStart.gif](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Data.Odbc;
using System.Data.OleDb;
using System.Data.OracleClient;
namespace DBAccessLayer
{
#region 访问数据库类型的枚举
/// <summary>
/// 名称: DBAccessType
/// 功能: 访问数据库类型的枚举
/// 作者: 张 亮
/// 版本: V1.0
/// 时间: 2008年5月14日
/// 修改人:
/// 修改时间:
/// 修改描述:
/// </summary>
public enum DBAccessType
{
SQL, // 以Sql形式访问数据库
ODBC, // 以Odbc形式访问数据库
OLEDB, // 以OleDb形式访问数据库
ORACLE // 以Oracle形式访问数据库
}
#endregion
#region 数据库访问工厂类
/// <summary>
/// 名称: DBAccessFactory
/// 功能: 数据库访问工厂类
/// 作者: 张 亮
/// 版本: V1.0
/// 时间: 2008年5月14日
/// 修改人:
/// 修改时间:
/// 修改描述:
/// </summary>
public class DBFactory
{
#region 获取数据库访问对象的静态方法
/// <summary>
/// 获取数据库访问对象的静态方法
/// </summary>
/// <param name="type">数据库访问的类型</param>
/// <param name="connectionString">访问数据库的连接字符串</param>
/// <returns>返回数据库访问对象(dbAccess)</returns>
public static IDBAccess GetDBAccess(DBAccessType type, string connectionString)
{
IDBAccess dbAccess = null;
switch (type)
{
case DBAccessType.SQL:
dbAccess = new DBAccess<SqlConnection, SqlCommand, SqlDataAdapter>(connectionString);
break;
case DBAccessType.ODBC:
dbAccess = new DBAccess<OdbcConnection, OdbcCommand, OdbcDataAdapter>(connectionString);
break;
case DBAccessType.OLEDB:
dbAccess = new DBAccess<OleDbConnection, OleDbCommand, OleDbDataAdapter>(connectionString);
break;
case DBAccessType.ORACLE:
dbAccess = new DBAccess<OracleConnection, OracleCommand, OracleDataAdapter>(connectionString);
break;
}
return dbAccess;
}
#endregion
}
#endregion
}
以上即是“数据库访问层”的完整部分,注释应该很详细了,代码细节我就不多说了,大家花费一点宝贵的时间仔细的把代码看完
应该就很清楚了。或许以上代码对刚接触.NET不久的新手带来一点点困惑,因为代码中用到接口、泛型、工厂模式等概念,最终希望我
的这点奉献精神能带给大家一点帮助,呵呵。