继承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. bzoj4318OSU &tyvj1952 Easy

    之前做tyvj1952Easy(给定一个序列,每个位置有一定的概率是1或0,求极长连续1的长度平方期望),用的做法是求出"全1子串的期望个数".假如每一段极长连续1分别长x1,x2 ...

  2. MongoDB: CURD操作

    >> 创建:·db.foo.insert({"bar":"baz"}) //如果文档中没有"_id"键会自动增加一个·db.fo ...

  3. Objective-C 再谈OC指针,对比C++/Java/Swift

    1.Objective-C的指针 OC一直是人感觉比较变态的一门语言,为什么呢?因为它的每个变量都是指针型,多的都几乎让人忘了那个*的存在了. 比如我定义了一个Student的Class,new了st ...

  4. sed命令给文本文件的每行的行首或者行尾添加文字

    在每行的头添加字符,比如"HEAD",命令如下: sed 's/^/HEAD&/g' test.file 在每行的行尾添加字符,比如“TAIL”,命令如下: sed 's/ ...

  5. 在CentOS上安装Sublime Text

    CentOS 是基于 Red Hat (RHEL) 的, 其中并没有包管理工具 apt. 最近需要在装了 CentOS 系统的服务器上安装Sublime Text, 到官网上看了一下, 对其他 (De ...

  6. 原生JS中常用的Window和DOM对象操作汇总

    一.常用的Window对象操作 Window对象中又包含了document.history.location.Navigator和screen几个对象,每个对象又有自己的属性方法,这里window可以 ...

  7. JSP+Servlet+javabean+mysql实现页面多条件模糊查询

    需求: 一般列表页上面会有一个查询框,有各种的查询条件组合,一般都采用模糊查询方式 ,以下以自己做的实例来说明一下实现方法: 需要实现的界面原型:要满足条件: 1.单选分类,点GO按扭 2.单独输入标 ...

  8. 【项目】iOS - 使用UIWebView占用内存过大

    通过其他博主介绍的解决这个问题的博客: http://blog.techno-barje.fr//post/2010/10/04/UIWebView-secrets-part1-memory-leak ...

  9. Knockoutjs的环境搭建教程

    最近要在项目中使用Knockoutjs,因此今天就首先研究了一下Knockoutjs的环境搭建,并进行了一个简单的测试,需要的朋友可以了解下 最近要在项目中使用Knockoutjs,因此今天就首先研究 ...

  10. IOS中在自定义控件(非视图控制器)的视图跳转中 代理方法与代码块的比较

    //代码块与代替代理的设计方法 我就以在自定义视图中(非视图控制器,不能实现视图控制功能),通过代理和代码块两种方法分别实现视图的跳转,进行对比 首先自定义了一个视图,上面有一个已经注册了得BUtto ...