一个简单实用的数据库访问层(转)
http://www.chenjiliang.com/Article/View.aspx?ArticleID=14479
我从学习Asp.Net(C#)开始到将其作为谋生工具至今已18月有余,当初有那么一阵对.NET的CLR很似痴迷,对C#2.0所带来的新特性也疯狂 不已。因为工作环境所迫,已经很久没有使用VS2005/2008作为自己的IDE了,一直在VS2003中煎熬的感觉已经让我失去了对痛苦的理解,或许 这也是逼迫我逐步转向前端开发的一个原动力吧。
这个“数据库访问层”的诞生是在我接触.NET和SQL Sever半年之后,在“师傅”的指点下通过硬背下代码,再到后来逐步加深对其实质的理 解,能够按照师傅的要求在18分钟准确无误的书写下每一行代码,那时所获得满足感,或许只有曾经有过类似经历的“战友”们才能体味。
该“数据库访问层”还有许多不太完善的地方,例如缺少事务的处理(对于现在我的来说,一般喜欢放在存储过程来完成)等,希望下列代码对大家有所帮助:
复制 保存
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 }
复制 保存
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 }
复制 保存
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不久的新手带来一点点困惑,因为代码中用到接口、泛型、工厂模式等概念,最终希望我的这点奉献精神能带给大家一点帮助,呵呵。