继承IDbConnection连接不同数据库
继承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连接不同数据库的更多相关文章
- C#连接Access数据库(详解)
做一个用VS2012的C#连接Access数据库的备忘, SQL数据库固然强大,有大微软的强力技术支持,LINQ的方便操作,但是如果写一个小程序对数据库方面没有什么大的要求的话,将来在数据库方面就可以 ...
- 利用jdbc连接oracle数据库
JDBC是Sun公司制定的一个可以用Java语言连接数据库的技术. 一.JDBC基础知识 JDBC(Java Data Base Connectivity,java 数据库连接)是一种用于执行SQL语 ...
- JDBC连接MySQL数据库及演示样例
JDBC是Sun公司制定的一个能够用Java语言连接数据库的技术. 一.JDBC基础知识 JDBC(Java Data Base Connectivity,java数据库连接)是一种用 ...
- JDBC连接MySQL数据库及示例
JDBC是Sun公司制定的一个可以用Java语言连接数据库的技术. 一.JDBC基础知识 JDBC(Java Data Base Connectivity,java数据库连接)是一 ...
- Windows server2008 搭建ASP接口访问连接oracle数据库全过程记录--备用
真的是太不容易了,以前的时候在window server 2003上面搭建了一套asp+oracle的接口系统,就费了好大的劲儿,其实那会迷迷瞪瞪的也不知道怎么的就弄好了,也懒得管了.OK,从昨天到今 ...
- JAVA采用JDBC连接操作数据库详解
JDBC连接数据库概述 一.JDBC基础知识 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供 ...
- python 连接操作数据库(二)
一.我们接着上期的博客继续对ORM框架进行补充,顺便把paramiko模块也给大家讲解一下: 1.ORM框架: 在连接操作数据库的第一个博客中也已经说了,sqlalchemy是一个ORM框架,总结就是 ...
- 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 ...
- EntityFramewok Core 1.1连接MSSql数据库详解
最近在研究ASP.NET Core,其中就用到了Entity Framework Core,对于Entity Framework Core连接SqlServer数据库,使用Code Frist创建数据 ...
随机推荐
- xudyh的gcd模板
hdu 5019 #include <cstdlib> #include <cctype> #include <cstring> #include <cstd ...
- joomla \libraries\joomla\session\session.php 反序列化截断畸形字符串导致对象注入漏洞
catalog . 漏洞描述 . PHP SESSION持久化 . PHP 序列化/反序列化内核实现 . 漏洞代码分析 . POC构造技巧 . 防御方案 . Code Pathc方案 1. 漏洞描述 ...
- JDBC连接简介
package jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; ...
- python deep copy and shallow copy
Python中对于对象的赋值都是引用,而不是拷贝对象(Assignment statements in Python do not copy objects, they create bindings ...
- JavaScript---认识JavaScipt
认识JavaScript 1.什么是JavaScript? JavaScript是属于网络的脚本语言,她被数百万计的网页用来改进设计.验证表单.检测浏览器.创建cookies以及更多的应用,她更是因特 ...
- css3实现小黄人
效果就像这样: 不废话,直接上代码! hrml代码: <!DOCTYPE html> <html> <head lang="zh"> <m ...
- c#优化
优化反射 http://kb.cnblogs.com/page/172119/ http://www.2cto.com/kf/201301/182765.html http://blog.sina.c ...
- 兼容ie6及一下版本的自适应
<meta http-equiv="X-UA-Compatible" content="IE=edge,Chrome=1" /> <meta ...
- PHP设计模式-策略模式 转
策略模式(Strategy Pattern) 策略模式是对象的行为模式,用意是对一组算法的封装.动态的选择需要的算法并使用. 策略模式指的是程序中涉及决策控制的一种模式.策略模式功能非常强大,因为这个 ...
- 自然语言15_Part of Speech Tagging with NLTK
https://www.pythonprogramming.net/part-of-speech-tagging-nltk-tutorial/?completed=/stemming-nltk-tut ...