继承IDbConnection连接不同数据库

本方案可实现仅修改app.config即可连接不同数据库,但是设计数据库时需要注意各种数据库的数据类型是不一样的。

各种不同数据库的Connection、Command、DataAdapter、Transaction和Parameter都继承自IDbConnection、IDbCommand、IDbDataAdapter、IDbTransaction和IDbDataParameter,用一个工厂来实现接口的实例即可实现连接不同数据库。

首先,需要新建一个类库,命名为DbManager,此类库需要5个文件,

1、创建一个枚举类型:DataProvider.cs

namespace DbManager

{

public enum DataProvider
    {
        Oracle,
        SqlServer,
        OleDb,
        Odbc,
        MySql
    }
}

2、创建一个工厂类,用来产生以上不同数据库的实例:DBManagerFactory.cs

using System.Data;
using System.Data.Odbc;
using System.Data.SqlClient;
using System.Data.OleDb;
using System.Data.OracleClient; //需要添加引用
using MySql.Data.MySqlClient;   //请自行安装MySQLConnector/Net后添加引用

namespace DbManager
{
    public sealed class DBManagerFactory
    {
        private DBManagerFactory()
        {
        }

public static IDbConnection GetConnection(DataProvider providerType)
        {
            IDbConnection iDbConnection;
            switch (providerType)
            {
                case DataProvider.SqlServer:
                    iDbConnection = new SqlConnection();
                    break;
                case DataProvider.OleDb:
                    iDbConnection = new OleDbConnection();
                    break;
                case DataProvider.Odbc:
                    iDbConnection = new OdbcConnection();
                    break;
                case DataProvider.Oracle:
                    iDbConnection = new OracleConnection();
                    break;
                case DataProvider.MySql:
                    iDbConnection = new MySqlConnection();
                    break;
                default:
                    return null;
            }
            return iDbConnection;
        }

public static IDbCommand GetCommand(DataProvider providerType)
        {
            switch (providerType)
            {
                case DataProvider.SqlServer:
                    return new SqlCommand();
                case DataProvider.OleDb:
                    return new OleDbCommand();
                case DataProvider.Odbc:
                    return new OdbcCommand();
                case DataProvider.Oracle:
                    return new OracleCommand();
                case DataProvider.MySql:
                    return new MySqlCommand();
                default:
                    return null;
            }
        }

public static IDbDataAdapter GetDataAdapter(DataProvider providerType)
        {
            switch (providerType)
            {
                case DataProvider.SqlServer:
                    return new SqlDataAdapter();
                case DataProvider.OleDb:
                    return new OleDbDataAdapter();
                case DataProvider.Odbc:
                    return new OdbcDataAdapter();
                case DataProvider.Oracle:
                    return new OracleDataAdapter();
                case DataProvider.MySql:
                    return new MySqlDataAdapter();
                default:
                    return null;
            }
        }

public static IDbTransaction GetTransaction(DataProvider providerType)
        {
            IDbConnection iDbConnection = GetConnection(providerType);
            IDbTransaction iDbTransaction = iDbConnection.BeginTransaction();
            return iDbTransaction;
        }

public static IDbDataParameter[] GetParameters(DataProvider providerType, int paramsCount)
        {
            IDbDataParameter[] idbParams = new IDbDataParameter[paramsCount];
            switch (providerType)
            {
                case DataProvider.SqlServer:
                    for (int i = 0; i < paramsCount; i++)
                    {
                        idbParams[i] = new SqlParameter();
                    }
                    break;
                case DataProvider.OleDb:
                    for (int i = 0; i < paramsCount; i++)
                    {
                        idbParams[i] = new OleDbParameter();
                    }
                    break;
                case DataProvider.Odbc:
                    for (int i = 0; i < paramsCount; i++)
                    {
                        idbParams[i] = new OdbcParameter();
                    }
                    break;
                case DataProvider.Oracle:
                    for (int i = 0; i < paramsCount; i++)
                    {
                        idbParams[i] = new OracleParameter();
                    }
                    break;
                case DataProvider.MySql:
                    for (int i = 0; i < paramsCount; i++)
                    {
                        idbParams[i] = new MySqlParameter();
                    }
                    break;
                default:
                    idbParams = null;
                    break;
            }
            return idbParams;
        }
    }
}

3、创建一个接口:IDBManager.cs

using System.Data;

namespace DbManager
{
    public interface IDBManager
    {
        DataProvider ProviderType
        {
            get;
            set;
        }

IDbConnection Connection
        {
            get;
            set;
        }

IDataReader DataReader
        {
            get;
            set;
        }

IDbCommand Command
        {
            get;
            set;
        }

IDbTransaction Transaction
        {
            get;
            set;
        }

IDbDataParameter[] Parameters
        {
            get;
            set;
        }

string ConnectionString
        {
            get;
            set;
        }

void Open();
        void Close();
        void Dispose();
        void CreateParameters(int paramsCount);
        void AddParameters(int index, string paramName, object objValue);
        void BeginTransaction();
        void CommitTransaction();
        void CloseReader();
        IDataReader ExecuteReader(CommandType commandType, string commandText);
        int ExecuteNonQuery(CommandType commandType, string commandText);
        object ExecuteScalar(CommandType commandType, string commandText);
        DataSet ExecuteDataSet(CommandType commandType, string commandText);
    }
}

4、创建一个类来实现IDBManager接口:DBManager.cs

using System;
using System.Data;

namespace DbManager
{
    public sealed class DBManager : IDBManager, IDisposable
    {
        #region 字段

private DataProvider _providerType;
        private IDbConnection _idbConnection;
        private IDataReader _iDataReader;
        private IDbCommand _idbCommand;
        private IDbTransaction _idbTransaction;
        private IDbDataParameter[] _idbParameters;
        private string _connectionString;

#endregion

#region 构造方法

public DBManager()
        {
        }

public DBManager(DataProvider providerType)
        {
            ProviderType = providerType;
        }

public DBManager(DataProvider providerType, string connectionString)
        {
            ProviderType = providerType;
            ConnectionString = connectionString;
        }

#endregion

#region 属性

public DataProvider ProviderType
        {
            get { return _providerType; }
            set { _providerType = value; }
        }

public IDbConnection Connection
        {
            get { return _idbConnection; }
            set { _idbConnection = value; }
        }

public IDataReader DataReader
        {
            get { return _iDataReader; }
            set { _iDataReader = value; }
        }

public IDbCommand Command
        {
            get { return _idbCommand; }
            set { _idbCommand = value; }
        }

public IDbTransaction Transaction
        {
            get { return _idbTransaction; }
            set { _idbTransaction = value; }
        }

public IDbDataParameter[] Parameters
        {
            get { return _idbParameters; }
            set { _idbParameters = value; }
        }

public string ConnectionString
        {
            get { return _connectionString; }
            set { _connectionString = value; }
        }

#endregion

#region 公有方法

public void Open()
        {
            Connection = DBManagerFactory.GetConnection(ProviderType);
            Connection.ConnectionString = ConnectionString;
            if (Connection.State != ConnectionState.Open)
            {
                Connection.Open();
            }
            Command = DBManagerFactory.GetCommand(ProviderType);
        }

public void Close()
        {
            if (Connection.State != ConnectionState.Closed)
            {
                Connection.Close();
            }
        }

public void Dispose()
        {
            GC.SuppressFinalize(this);
            Close();
            Command = null;
            Transaction = null;
            Connection = null;
        }

public void CreateParameters(int paramsCount)
        {
            Parameters = new IDbDataParameter[paramsCount];
            Parameters = DBManagerFactory.GetParameters(ProviderType, paramsCount);
        }

public void AddParameters(int index, string paramName, object objValue)
        {
            if (index < Parameters.Length)
            {
                Parameters[index].ParameterName = paramName;
                Parameters[index].Value = objValue;
            }
        }

public void BeginTransaction()
        {
            if (Transaction == null)
            {
                Transaction = DBManagerFactory.GetTransaction(ProviderType);
            }
            Command.Transaction = Transaction;
        }

public void CommitTransaction()
        {
            if (Transaction != null)
            {
                Transaction.Commit();
            }
            Transaction = null;
        }

public void CloseReader()
        {
            if (DataReader != null)
            {
                DataReader.Close();
            }
        }

public IDataReader ExecuteReader(CommandType commandType, string commandText)
        {
            Command = DBManagerFactory.GetCommand(ProviderType);
            Command.Connection = Connection;
            PrepareCommand(Command, Connection, Transaction, commandType, commandText, Parameters);
            DataReader = Command.ExecuteReader();
            Command.Parameters.Clear();
            return DataReader;
        }

public int ExecuteNonQuery(CommandType commandType, string commandText)
        {
            Command = DBManagerFactory.GetCommand(ProviderType);
            PrepareCommand(Command, Connection, Transaction, commandType, commandText, Parameters);
            int returnValue = Command.ExecuteNonQuery();
            Command.Parameters.Clear();
            return returnValue;
        }

public object ExecuteScalar(CommandType commandType, string commandText)
        {
            Command = DBManagerFactory.GetCommand(ProviderType);
            PrepareCommand(Command, Connection, Transaction, commandType, commandText, Parameters);
            object returnValue = Command.ExecuteScalar();
            Command.Parameters.Clear();
            return returnValue;
        }

public DataSet ExecuteDataSet(CommandType commandType, string commandText)
        {
            Command = DBManagerFactory.GetCommand(ProviderType);
            PrepareCommand(Command, Connection, Transaction, commandType, commandText, Parameters);
            IDbDataAdapter dataAdapter = DBManagerFactory.GetDataAdapter(ProviderType);
            dataAdapter.SelectCommand = Command;
            DataSet dataSet = new DataSet();
            dataAdapter.Fill(dataSet);
            Command.Parameters.Clear();
            return dataSet;
        }

#endregion

#region 私有方法

private void AttachParameters(IDbCommand command, IDbDataParameter[] commandParameters)
        {
            foreach (IDbDataParameter idbParameter in commandParameters)
            {
                if (idbParameter.Direction == ParameterDirection.InputOutput && idbParameter.Value == null)
                {
                    idbParameter.Value = DBNull.Value;
                }
                command.Parameters.Add(idbParameter);
            }
        }

private void PrepareCommand(IDbCommand command, IDbConnection connection, IDbTransaction transaction,
                                    CommandType commandType, string commandText, IDbDataParameter[] commandParameters)
        {
            command.Connection = connection;
            command.CommandText = commandText;
            command.CommandType = commandType;
            if (transaction != null)
            {
                command.Transaction = transaction;
            }
            if (commandParameters != null)
            {
                AttachParameters(command, commandParameters);
            }
        }

#endregion
    }
}

5、再加一个DBHelper.cs,来调用DBManager类,外部来直接调用DBHelper类即可。

using System;
using System.Data;
using System.Configuration;

namespace DbManager
{
    public class DBHelper
    {
        private static readonly IDBManager dbManager = new DBManager(GetDataProvider(), GetConnectionString());

/// <summary>
        /// 从配置文件中选择数据库类型
        /// </summary>
        /// <returns>DataProvider枚举值</returns>
        private static DataProvider GetDataProvider()
        {
            string providerType = ConfigurationManager.AppSettings["DataProvider"];
            DataProvider dataProvider;
            switch (providerType)
            {
                case "Oracle":
                    dataProvider = DataProvider.Oracle;
                    break;
                case "SqlServer":
                    dataProvider = DataProvider.SqlServer;
                    break;
                case "OleDb":
                    dataProvider = DataProvider.OleDb;
                    break;
                case "Odbc":
                    dataProvider = DataProvider.Odbc;
                    break;
                case "MySql":
                    dataProvider = DataProvider.MySql;
                    break;
                default:
                    return DataProvider.Odbc;
            }
            return dataProvider;
        }

/// <summary>
        /// 从配置文件获取连接字符串
        /// </summary>
        /// <returns>连接字符串</returns>
        private static string GetConnectionString()
        {
            return ConfigurationManager.ConnectionStrings["ConnString"].ConnectionString;
        }

/// <summary>
        /// 关闭数据库连接的方法
        /// </summary>
        public static void Close()
        {
            dbManager.Dispose();
        }

/// <summary>
        /// 创建参数
        /// </summary>
        /// <param name="paramsCount">参数个数</param>
        public static void CreateParameters(int paramsCount)
        {
            dbManager.CreateParameters(paramsCount);
        }

/// <summary>
        /// 添加参数
        /// </summary>
        /// <param name="index">参数索引</param>
        /// <param name="paramName">参数名</param>
        /// <param name="objValue">参数值</param>
        public static void AddParameters(int index, string paramName, object objValue)
        {
            dbManager.AddParameters(index, paramName, objValue);
        }

/// <summary>
        /// 执行增删改
        /// </summary>
        /// <param name="sqlString">安全的sql语句string.Format()</param>
        /// <returns>操作成功返回true</returns>
        public static bool ExecuteNonQuery(string sqlString)
        {
            try
            {
                dbManager.Open();
                return dbManager.ExecuteNonQuery(CommandType.Text, sqlString) > 0 ? true : false;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
            finally
            {
                dbManager.Dispose();
            }
        }

/// <summary>
        /// 执行查询
        /// </summary>
        /// <param name="sqlString">安全的sql语句string.Format()</param>
        /// <returns>返回IDataReader</returns>
        public static IDataReader ExecuteReader(string sqlString)
        {
            try
            {
                dbManager.Open();
                return dbManager.ExecuteReader(CommandType.Text, sqlString);
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }
    }
}

现在,将上述项目生成一个DbManager.dll类库,在具体的DAL层里面就可以直接调用了。

DBHelper类没有全部写完,只写了ExecuteNonQuery()和ExecuteReader()两个方法,对于有参和无参的增删改查操作暂时够用,返回DataSet的方法未写,Transaction相关的也未写。

6、app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <connectionStrings>
        <add name="ConnString" connectionString="server=localhost;database=yourDbName;Persist Security Info=False;uid=root;pwd=mysqladmin"/>
        <!-- 通过改变ConnectionString的值来更换数据库连接字符串
        <add name="ConnString" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=DBDemo.mdb;Jet OLEDB:Database Password=1234"/>
        <add name="ConnString" connectionString="server=localhost;database=yourDbName;Persist Security Info=False;Integrated Security=SSPI"/>
        <add name="ConnString" connectionString="server=localhost;database=yourDbName;Persist Security Info=False;uid=sa;pwd=1234"/>
        <add name="ConnString" connectionString="server=localhost;database=yourDbName;Persist Security Info=False;uid=root;pwd=mysqladmin"/>
        -->
    </connectionStrings>
    <appSettings>
        <add key="DataProvider" value="MySql"/>
        <!-- 通过改变value值来更换数据库
        <add key="DataProvider" value="Oracle"/>
        <add key="DataProvider" value="SqlServer"/>
        <add key="DataProvider" value="OleDb"/>
        <add key="DataProvider" value="Odbc"/> 
        <add key="DataProvider" value="MySql"/>
        -->
    </appSettings>
</configuration>

7、程序中的调用

举个简单的例子,我们就创建一个控制台应用程序,然后添加DbManager.dll的引用

Program.cs文件的样子:

using System;
using System.Data;
using DbManager;  //记得引入命名空间

namespace DBDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            SelectWithoutParams();
            Console.WriteLine("------安全sql语句string.Format()的查询结果------");
            SelectWithSafeSql(4);
            Console.WriteLine("------参数化语句的查询结果-------");
            SelectWithParams("总统套间");

}

private static void SelectWithoutParams()

{
            const string sql = "select * from RoomType";
            IDataReader reader = DBHelper.ExecuteReader(sql);
            while (reader.Read())
            {
                Console.WriteLine(reader["TypeName"].ToString());
            }
            DBHelper.Close();  //记得关闭reader
        }

private static void SelectWithSafeSql(int TypeId)
        {
            string sql = string.Format("select * from RoomType where TypeId={0}", TypeId);
            IDataReader reader = DBHelper.ExecuteReader(sql);
            while (reader.Read())
            {
                Console.WriteLine(reader["TypeName"].ToString());
            }
            DBHelper.Close();
        }

private static void SelectWithParams(string typeName)
        {

string sql = "select * from RoomType where TypeName=@TypeName";

//先创建参数,然后才能添加参数

DBHelper.CreateParameters(1);  //参数个数,1个
            DBHelper.AddParameters(0, "@TypeName", typeName);
            IDataReader reader = DBHelper.ExecuteReader(sql);
            while (reader.Read())
            {
                Console.WriteLine(reader["TypeName"].ToString());
            }
            DBHelper.Close();
        }
    }
}

OK!全部完成!在具体的DAL层中,调用DBHelper的相关方法即可,如果是查询方法,记得最后要写关闭代码。只要表结构一样,可以在app.config中随意切换数据库。

最后注意的是:

各个数据库的插入语句不一样,假设我们有4个字段,第一个字段fieldName1为自增字段。

对于SQLServer,不需要写自增字段,

语句是:INSERT INTO table VALUES(value2, value3, value4);

对于MySQL,自增字段位置需要写null代替,

语句是:INSERT INTO table VALUES(NULL, value2, value3, value4);

而对于ACCESS数据库,则必须写完整,

语句是:INSERT INTO table(fieldName2, fieldName3,fieldName4) VALUES(value2, value3, value4);

为了实现兼容,大家还是都按完整的来写,就不会有错了。

转自:http://www.cnblogs.com/top5/archive/2011/08/01/2123971.html

继承IDbConnection连接不同数据库的更多相关文章

  1. C#连接Access数据库(详解)

    做一个用VS2012的C#连接Access数据库的备忘, SQL数据库固然强大,有大微软的强力技术支持,LINQ的方便操作,但是如果写一个小程序对数据库方面没有什么大的要求的话,将来在数据库方面就可以 ...

  2. 利用jdbc连接oracle数据库

    JDBC是Sun公司制定的一个可以用Java语言连接数据库的技术. 一.JDBC基础知识 JDBC(Java Data Base Connectivity,java 数据库连接)是一种用于执行SQL语 ...

  3. JDBC连接MySQL数据库及演示样例

    JDBC是Sun公司制定的一个能够用Java语言连接数据库的技术. 一.JDBC基础知识         JDBC(Java Data Base Connectivity,java数据库连接)是一种用 ...

  4. JDBC连接MySQL数据库及示例

      JDBC是Sun公司制定的一个可以用Java语言连接数据库的技术. 一.JDBC基础知识         JDBC(Java Data Base Connectivity,java数据库连接)是一 ...

  5. Windows server2008 搭建ASP接口访问连接oracle数据库全过程记录--备用

    真的是太不容易了,以前的时候在window server 2003上面搭建了一套asp+oracle的接口系统,就费了好大的劲儿,其实那会迷迷瞪瞪的也不知道怎么的就弄好了,也懒得管了.OK,从昨天到今 ...

  6. JAVA采用JDBC连接操作数据库详解

    JDBC连接数据库概述 一.JDBC基础知识 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供 ...

  7. python 连接操作数据库(二)

    一.我们接着上期的博客继续对ORM框架进行补充,顺便把paramiko模块也给大家讲解一下: 1.ORM框架: 在连接操作数据库的第一个博客中也已经说了,sqlalchemy是一个ORM框架,总结就是 ...

  8. jsp-3 简单的servlet连接mysql数据库 使用mvc的登录注册

    简单的servlet连接mysql数据库 使用mvc的登录注册 commons-dbutils-1.6 mysql-connector-java-5.1.40-bin c3p0-0.9.5.2 mch ...

  9. EntityFramewok Core 1.1连接MSSql数据库详解

    最近在研究ASP.NET Core,其中就用到了Entity Framework Core,对于Entity Framework Core连接SqlServer数据库,使用Code Frist创建数据 ...

随机推荐

  1. AutoIt3(AU3)开发的智能驱动安装工具,用于系统封装,支持参数静默启动

    项目相关地址 源码:https://github.com/easonjim/Smart_Driver bug提交:https://github.com/easonjim/Smart_Driver

  2. linux系统安装配置

    以中文拼音输入法为例:1.sudo apt install ibus-pinyin2.sudo apt install ibus-libpinyin3.注销重新登录 或则 重启计算机4.进入输入设置, ...

  3. python字符串格式化输出

    python格式化输出 python格式化输出有两种方式:百分号和format format的功能要比百分号方式强大,其中format独有的可以自定义字符填充空白.字符串居中显示.转换二进制.整数自动 ...

  4. POJ 1804 Brainman(归并排序)

    传送门 Description Background Raymond Babbitt drives his brother Charlie mad. Recently Raymond counted ...

  5. 团队项目UML用例图

    团队项目UML用例图

  6. C++ STL中vector的内存机制和性能分析

    vecotr是动态数组,顾名思义他可以动态的增加自己的长度. 内存机制: 但是怎样的增加自己的长度? vector有两个函数一个是capacity()返回内存空间即缓冲区的大小,另一个是size()返 ...

  7. Git连接到Git@OSC

    1.配置本地git $git config --global user.name "xxx" $git config --global user.email "xxxxx ...

  8. ios动态添加属性的几种方法

    http://blog.csdn.net/shengyumojian/article/details/44919695 在ios运行过程中,有几种方式能够动态的添加属性. 1-通过runtime动态关 ...

  9. JS获取select选中的值,所有option值

    <select name="myselect" id="myselect"> <option value="2042"&g ...

  10. 《高性能MySQL》读书笔记--锁、事务、隔离级别 转

    1.锁 为什么需要锁?因为数据库要解决并发控制问题.在同一时刻,可能会有多个客户端对表中同一行记录进行操作,比如有的在读取该行数据,其他的尝试去删除它.为了保证数据的一致性,数据库就要对这种并发操作进 ...