一个简单实用的数据库访问层(转)

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不久的新手带来一点点困惑,因为代码中用到接口、泛型、工厂模式等概念,最终希望我的这点奉献精神能带给大家一点帮助,呵呵。

posted @ 2011-12-13 15:18  董雨  阅读(383)  评论(0编辑  收藏  举报