继承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创建数据 ...
随机推荐
- hdu 1757 矩阵
用矩阵表示状态,矩阵乘法的就是状态之间的变换 作一个vector: 要求的就是一个矩阵A,使得上面那个vector乘以A之后变成 解得A= [不知道用逆矩阵能不能直接求出A Ref:http://bl ...
- bzoj2588 Count on a tree
题意:给定一棵树,有点权,不带修改,询问路径点权第K大,强制在线. 这道题建主席树的方法好机智.按照BFS/DFS序建树,对于每个点,建出"这个点到根节点的路径上的点"组成的权值线 ...
- COGS103&tyvj1899 [NOIP2002]矩形覆盖
题目里给的范围是k<=4,但是官方数据并没有k==4的情况,导致一些奇奇怪怪的DP写法也能过.听说标程在k==4的时候有反例,掀桌-.. 难怪COGS上k==4的数据答案是错的. 还是好好写个搜 ...
- 开发一个jQuery插件——多级联动菜单
引言 开发中,有好多地方用到联动菜单,以前每次遇到联动菜单的时候都去重新写,代码重用率很低,前几天又遇到联动菜单的问题,总结了下,发现可以开发一个联动菜单的功能,以后想用的时候就方便多了.项目中每个页 ...
- EF 知识点
EntityFrameWorak知识点记录 发展史 EF1.0时,只支持Database First,数据库优先.必须将设计器指向一个现有的数据库. EF4时,支持Model First,模型优先.可 ...
- 【Alpha版本】 第九天 11.17
一.站立式会议照片: 二.项目燃尽图: 三.项目进展: 成 员 昨天完成任务 今天完成任务 明天要做任务 问题困难 心得体会 胡泽善 完成我要应聘的详情显示,解决头像不能显示的问题,完成了报名及取消操 ...
- HDU 4280Island Transport(Dinc非STL 模板)
题意: n岛m条路,然后是 n个岛的坐标,然后是m条双向路,包括 岛和 岛 之间 最大客流量,让求 最左边的岛 到右边的岛 最大客流量 分析: 建图 以 左边的岛为原点,最右边的为终点求最大客流量. ...
- Git连接到Git@OSC
1.配置本地git $git config --global user.name "xxx" $git config --global user.email "xxxxx ...
- 实现BPEL4WS演示:教程
http://www.ibm.com/developerworks/cn/education/webservices/ws-bpelws/bpel_tutorial_cn.html 开始 什么是Bus ...
- SSH项目与SSM项目的进入首页的方法
SSH项目中: jsp页面一般都是存放在WEB-INF下面的目录下,这样我们就不能直接访问到这些jsp页面了,保证了页面的安全性. 在struts的管理中,是利用action来实现页面的跳转,进入in ...