万能的SqlHelper,麻麻再也不用担心用什么数据库了

时间:2022-10-08 00:42:48

以前只用一种数据库,倒也无所谓,但是再数据库切换的时候,发现代码差不多呀。

最初,两种数据库,大不了写两个SqlHelper,但是多了也就发现代码重用率太低了吧。

因此,下面的SqlHelper诞生了。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;

namespace WangSql.DBUtility
{
    public static class SqlHelperExt
    {
        public static int AddRange(this IDataParameterCollection coll, IDataParameter[] par)
        {
            int i = 0;
            foreach (var item in par)
            {
                coll.Add(item);
                i++;
            }
            return i;
        }
    }

    #region SqlHelper
    public class SqlHelper
    {
        private IDbConnection conn = null;
        private IDbCommand cmd = null;
        private IDataReader dr = null;
        private DbType type = DbType.NONE;

        #region 创建数据库连接
        /// <summary>
        /// 创建数据库连接
        /// </summary>
        public SqlHelper(string connectionString)
        {
            conn = DBFactory.CreateDbConnection(type, connectionString);
        }
        #endregion

        #region 判断并打开conn
        /// <summary>
        /// 判断并打开conn
        /// </summary>
        /// <returns></returns>
        public IDbConnection CreatConn()
        {
            if (conn.State == ConnectionState.Closed)
            {
                conn.Open();
            }
            return conn;
        }
        #endregion

        #region 执行查询sql语句
        /// <summary>
        /// 执行查询sql语句
        /// </summary>
        /// <param name="sql">查询sql语句</param>
        /// <returns>返回一个表</returns>
        public DataTable ExecuteReader(string sql)
        {
            DataTable dt = new DataTable();
            using (cmd = DBFactory.CreateDbCommand(sql, CreatConn()))
            {
                using (dr = cmd.ExecuteReader())
                {
                    dt.Load(dr);
                }
            }
            conn.Close();
            return dt;
        }
        #endregion

        #region 执行查询带参的sql语句
        /// <summary>
        /// 执行查询带参的sql语句
        /// </summary>
        /// <param name="sql">查询sql语句</param>
        /// <param name="par">sql语句中的参数</param>
        /// <returns>返回一个表</returns>
        public DataTable ExecuteReader(string sql, IDataParameter[] par)
        {
            DataTable dt = new DataTable();
            using (cmd = DBFactory.CreateDbCommand(sql, CreatConn()))
            {
                cmd.Parameters.AddRange(par);
                using (dr = cmd.ExecuteReader())
                {
                    dt.Load(dr);
                }
            }
            conn.Close();
            return dt;
        }
        public DataTable ExecuteReader(string sql, IDataParameter par)
        {
            DataTable dt = new DataTable();
            using (cmd = DBFactory.CreateDbCommand(sql, CreatConn()))
            {
                cmd.Parameters.Add(par);
                using (dr = cmd.ExecuteReader())
                {
                    dt.Load(dr);
                }
            }
            conn.Close();
            return dt;
        }
        #endregion

        #region 执行增,删,改sql语句
        /// <summary>
        /// 执行无参的增,删,改sql语句
        /// </summary>
        /// <param name="sql">增,删,改的sql语句</param>
        /// <param name="par">sql语句中的参数</param>
        /// <returns>返回所影响的行数</returns>
        public int ExecuteNonQuery(string sql)
        {
            int result = 0;
            using (cmd = DBFactory.CreateDbCommand(sql, CreatConn()))
            {
                result = cmd.ExecuteNonQuery();
            }
            conn.Close();
            return result;
        }
        #endregion

        #region 执行带参的增,删,改sql语句
        /// <summary>
        /// 执行带参的增,删,改sql语句
        /// </summary>
        /// <param name="sql">增,删,改的sql语句</param>
        /// <param name="par">sql语句中的参数</param>
        /// <returns>返回所影响的行数</returns>
        public int ExecuteNonQuery(string sql, IDbDataParameter[] par)
        {
            int result = 0;
            using (cmd = DBFactory.CreateDbCommand(sql, CreatConn()))
            {
                cmd.Parameters.AddRange(par);
                result = cmd.ExecuteNonQuery();
            }
            conn.Close();
            return result;
        }
        public int ExecuteNonQuery(string sql, IDbDataParameter par)
        {
            int result = 0;
            using (cmd = DBFactory.CreateDbCommand(sql, CreatConn()))
            {
                cmd.Parameters.Add(par);
                result = cmd.ExecuteNonQuery();
            }
            conn.Close();
            return result;
        }
        #endregion

        #region 事务
        /// <summary>
        /// 执行多条SQL语句,实现数据库事务。
        /// </summary>
        /// <param name="SQLList">SQL语句的哈希表(key为sql语句,value是该语句的OleDbParameter[])</param>
        public bool ExecuteTransaction(Hashtable SqlList)
        {
            CreatConn();
            using (IDbTransaction trans = conn.BeginTransaction())
            {
                IDbCommand cmd = DBFactory.CreateDbCommand(type);
                try
                {
                    //循环
                    foreach (DictionaryEntry myDE in SqlList)
                    {
                        string cmdText = myDE.Key.ToString();
                        IDbDataParameter[] cmdParms = (IDbDataParameter[])myDE.Value;
                        PrepareCommand(cmd, conn, trans, cmdText, cmdParms);
                        int val = cmd.ExecuteNonQuery();
                        cmd.Parameters.Clear();
                    }
                    trans.Commit();
                }
                catch
                {
                    trans.Rollback();
                    return false;
                }
                finally
                {
                    conn.Close();
                }
            }
            return true;
        }

        private void PrepareCommand(IDbCommand cmd, IDbConnection conn, IDbTransaction trans, string cmdText, IDataParameter[] cmdParms)
        {
            CreatConn();
            cmd.Connection = conn;
            cmd.CommandText = cmdText;
            if (trans != null)
                cmd.Transaction = trans;
            cmd.CommandType = CommandType.Text;//cmdType;
            if (cmdParms != null)
                cmd.Parameters.AddRange(cmdParms);
        }
        #endregion
    }
    #endregion
}

上面是核心代码,上面有个扩展。主要是是由于抽象类里面不包含AddRange方法。楼主也是懒得改原来的方法,也是为了和原来的SqlHelper保持一致,干脆就直接扩展了一个AddRange。

好了,既然是全是抽象参数,实际中,还是需要实例化具体某种数据库的实例的,所以还需要一个创建各个数据库实例的工厂了。

using MySql.Data.MySqlClient;
using Oracle.DataAccess.Client;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.Data.SqlClient;
using System.Data.SQLite;
using System.Linq;
using System.Text;

namespace WangSql
{
    public enum DbType
    {
        //Oracle,SqlServer,MySql,Access,SqlLite
        NONE,
        ORACLE,
        SQLSERVER,
        MYSQL,
        ACCESS,
        SQLLITE
    }

    public class DBFactory
    {
        public static IDbConnection CreateDbConnection(DbType type, string connectionString)
        {
            IDbConnection conn = null;
            switch (type)
            {
                case DbType.ORACLE:
                    conn = new OracleConnection(connectionString);
                    break;
                case DbType.SQLSERVER:
                    conn = new SqlConnection(connectionString);
                    break;
                case DbType.MYSQL:
                    conn = new MySqlConnection(connectionString);
                    break;
                case DbType.ACCESS:
                    conn = new OleDbConnection(connectionString);
                    break;
                case DbType.SQLLITE:
                    conn = new SQLiteConnection(connectionString);
                    break;
                case DbType.NONE:
                    throw new Exception("未设置数据库类型");
                default:
                    throw new Exception("不支持该数据库类型");
            }
            return conn;
        }


        public static IDbCommand CreateDbCommand(DbType type)
        {
            IDbCommand cmd = null;
            switch (type)
            {
                case DbType.ORACLE:
                    cmd = new OracleCommand();
                    break;
                case DbType.SQLSERVER:
                    cmd = new SqlCommand();
                    break;
                case DbType.MYSQL:
                    cmd = new MySqlCommand();
                    break;
                case DbType.ACCESS:
                    cmd = new OleDbCommand();
                    break;
                case DbType.SQLLITE:
                    cmd = new SQLiteCommand();
                    break;
                case DbType.NONE:
                    throw new Exception("未设置数据库类型");
                default:
                    throw new Exception("不支持该数据库类型");
            }
            return cmd;
        }
        public static IDbCommand CreateDbCommand(string sql, IDbConnection conn)
        {
            DbType type = DbType.NONE;
            if (conn is OracleConnection)
                type = DbType.ORACLE;
            else if (conn is SqlConnection)
                type = DbType.SQLSERVER;
            else if (conn is MySqlConnection)
                type = DbType.MYSQL;
            else if (conn is OleDbConnection)
                type = DbType.ACCESS;
            else if (conn is SQLiteConnection)
                type = DbType.SQLLITE;

            IDbCommand cmd = null;
            switch (type)
            {
                case DbType.ORACLE:
                    cmd = new OracleCommand(sql, (OracleConnection)conn);
                    break;
                case DbType.SQLSERVER:
                    cmd = new SqlCommand(sql, (SqlConnection)conn);
                    break;
                case DbType.MYSQL:
                    cmd = new MySqlCommand(sql, (MySqlConnection)conn);
                    break;
                case DbType.ACCESS:
                    cmd = new OleDbCommand(sql, (OleDbConnection)conn);
                    break;
                case DbType.SQLLITE:
                    cmd = new SQLiteCommand(sql, (SQLiteConnection)conn);
                    break;
                case DbType.NONE:
                    throw new Exception("未设置数据库类型");
                default:
                    throw new Exception("不支持该数据库类型");
            }
            return cmd;
        }


    }
}

 

哈哈,即使再来一个数据库,你试试看,是不是很简单呢。

对了,上面的SqlHelper再单例模式下是有问题的哦,这个请大家提出下好的建议。