兼容SQLSERVER、Oracle、MYSQL、SQLITE的超级DBHelper
本示例代码的关键是利用.net库自带的DbProviderFactory来生产数据库操作对象。
从下图中,可以看到其的多个核心方法,这些方法将在我们的超级DBHelper中使用。

仔细研究,你会发现每个数据库的官方支持dll都有一个Instance对象,这个对象都是继承了DbProviderFactory了。
因此利用这点,我们就可以实现兼容多种数据的超级DBHelper了。
以下为示例代码,仅供参考学习,代码只是我的ORM框架中的一个片段(其中暂时支持了SQLSERVER、MySQL、SQLITE三种数据库,LoadDbProviderFactory方法是将封装在dll中的数据库操作dll反射加载实例化的方法。):
/// <summary>
/// 超级数据库操作类
/// <para>2015年12月21日</para>
/// </summary>
public class DBHelper
{
#region 属性
private DbProviderFactory _DbFactory;
private DBConfig mDBConfig; /// <summary>
/// 数据库连接配置
/// </summary>
public DBConfig DBConfig
{
get { return mDBConfig; }
} /// <summary>
/// 表示一组方法,这些方法用于创建提供程序对数据源类的实现的实例。
/// </summary>
public DbProviderFactory DbFactory
{
get { return _DbFactory; }
set { _DbFactory = value; }
}
#endregion #region 构造函数
public DBHelper(DBConfig aORMConfig)
{
mDBConfig = aORMConfig;
switch (mDBConfig.DBType)
{
case ORMType.DBTypes.SQLSERVER:
_DbFactory = System.Data.SqlClient.SqlClientFactory.Instance;
break;
case ORMType.DBTypes.MYSQL:
LoadDbProviderFactory("MySql.Data.dll", "MySql.Data.MySqlClient.MySqlClientFactory");
break;
case ORMType.DBTypes.SQLITE:
LoadDbProviderFactory("System.Data.SQLite.dll", "System.Data.SQLite.SQLiteFactory");
break;
}
} /// <summary>
/// 动态载入数据库封装库
/// </summary>
/// <param name="aDLLName">数据库封装库文件名称</param>
/// <param name="aFactoryName">工厂路径名称</param>
private void LoadDbProviderFactory(string aDLLName, string aFactoryName)
{
string dllPath = string.Empty;
if (System.AppDomain.CurrentDomain.RelativeSearchPath != null)
{
dllPath = System.AppDomain.CurrentDomain.RelativeSearchPath+"\\"+ aDLLName;
}
else
{
dllPath = System.AppDomain.CurrentDomain.BaseDirectory + aDLLName;
}
if (!File.Exists(dllPath))
{//文件不存在,从库资源中复制输出到基目录下
FileStream fdllFile = new FileStream(dllPath,FileMode.Create);
byte[] dllData = null;
if (aDLLName == "System.Data.SQLite.dll")
{
dllData = YFmk.ORM.Properties.Resources.System_Data_SQLite;
}
else if (aDLLName == "MySql.Data.dll")
{
dllData = YFmk.ORM.Properties.Resources.MySql_Data;
}
fdllFile.Write(dllData, , dllData.Length);
fdllFile.Close();
}
Assembly libAssembly = Assembly.LoadFile(dllPath);
Type type = libAssembly.GetType(aFactoryName);
foreach (FieldInfo fi in type.GetFields(BindingFlags.Static | BindingFlags.Public))
{
if (fi.Name == "Instance")
{
_DbFactory = fi.GetValue(null) as DbProviderFactory;
return;
}
}
}
#endregion #region 数据库操作
/// <summary>
/// 执行一条计算查询结果语句,返回查询结果
/// </summary>
/// <param name="aSQLWithParameter">SQL语句及参数</param>
/// <returns>查询结果(object)</returns>
public object GetSingle(SQLWithParameter aSQLWithParameter)
{
using (DbConnection conn = _DbFactory.CreateConnection())
{
conn.ConnectionString = mDBConfig.ConnString;
using (DbCommand cmd = _DbFactory.CreateCommand())
{
PrepareCommand(cmd, conn, aSQLWithParameter.SQL.ToString(), aSQLWithParameter.Parameters);
object obj = cmd.ExecuteScalar();
cmd.Parameters.Clear();
if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
{
return null;
}
else
{
return obj;
}
}
}
} /// <summary>
/// 执行SQL语句,返回影响的记录数
/// </summary>
/// <param name="aSQL">SQL语句</param>
/// <returns>影响的记录数</returns>
public int ExecuteSql(string aSQL)
{
using (DbConnection conn = _DbFactory.CreateConnection())
{
conn.ConnectionString = mDBConfig.ConnString;
using (DbCommand cmd = _DbFactory.CreateCommand())
{
PrepareCommand(cmd, conn, aSQL);
int rows = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return rows;
}
}
} /// <summary>
/// 执行SQL语句,返回影响的记录数
/// </summary>
/// <param name="aSQLWithParameter">SQL语句及参数</param>
/// <returns></returns>
public int ExecuteSql(SQLWithParameter aSQLWithParameter)
{
using (DbConnection conn = _DbFactory.CreateConnection())
{
conn.ConnectionString = mDBConfig.ConnString;
using (DbCommand cmd = _DbFactory.CreateCommand())
{
PrepareCommand(cmd, conn, aSQLWithParameter.SQL.ToString(), aSQLWithParameter.Parameters);
int rows = cmd.ExecuteNonQuery();
cmd.Parameters.Clear();
return rows;
}
}
} /// <summary>
/// 执行多条SQL语句,实现数据库事务。
/// </summary>
/// <param name="aSQLWithParameterList">参数化的SQL语句结构体对象集合</param>
public string ExecuteSqlTran(List<SQLWithParameter> aSQLWithParameterList)
{
using (DbConnection conn = _DbFactory.CreateConnection())
{
conn.ConnectionString = mDBConfig.ConnString;
conn.Open();
DbTransaction fSqlTransaction = conn.BeginTransaction();
try
{
List<DbCommand> fTranCmdList = new List<DbCommand>();
//创建新的CMD
DbCommand fFirstCMD = _DbFactory.CreateCommand();
fFirstCMD.Connection = conn;
fFirstCMD.Transaction = fSqlTransaction;
fTranCmdList.Add(fFirstCMD);
int NowCmdIndex = ;//当前执行的CMD索引值
int ExecuteCount = ;//已经执行的CMD次数
StringBuilder fSQL = new StringBuilder();
foreach (SQLWithParameter fSQLWithParameter in aSQLWithParameterList)
{
fSQL.Append(fSQLWithParameter.SQL.ToString() + ";");
fTranCmdList[NowCmdIndex].Parameters.AddRange(fSQLWithParameter.Parameters.ToArray());
if (fTranCmdList[NowCmdIndex].Parameters.Count > )
{ //参数达到2000个,执行一次CMD
fTranCmdList[NowCmdIndex].CommandText = fSQL.ToString();
fTranCmdList[NowCmdIndex].ExecuteNonQuery();
DbCommand fNewCMD = _DbFactory.CreateCommand();
fNewCMD.Connection = conn;
fNewCMD.Transaction = fSqlTransaction;
fTranCmdList.Add(fNewCMD);
NowCmdIndex++;
ExecuteCount++;
fSQL.Clear();//清空SQL
}
}
if (ExecuteCount < fTranCmdList.Count)
{//已执行CMD次数小于总CMD数,执行最后一条CMD
fTranCmdList[fTranCmdList.Count - ].CommandText = fSQL.ToString();
fTranCmdList[fTranCmdList.Count - ].ExecuteNonQuery();
}
fSqlTransaction.Commit();
return null;
}
catch (Exception ex)
{
fSqlTransaction.Rollback();
StringBuilder fSQL = new StringBuilder();
foreach (SQLWithParameter fSQLWithParameter in aSQLWithParameterList)
{
fSQL.Append(fSQLWithParameter.SQL.ToString() + ";");
}
YFmk.Lib.LocalLog.WriteByDate(fSQL.ToString()+" 错误:"+ex.Message, "ORM");
return ex.Message;
}
}
} /// <summary>
/// 执行查询语句,返回DataSet
/// </summary>
/// <param name="SQLString">查询语句</param>
/// <returns>DataSet</returns>
public DataSet Query(string SQLString)
{
using (DbConnection conn = _DbFactory.CreateConnection())
{
conn.ConnectionString = mDBConfig.ConnString;
using (DbCommand cmd = _DbFactory.CreateCommand())
{
PrepareCommand(cmd, conn, SQLString);
using (DbDataAdapter da = _DbFactory.CreateDataAdapter())
{
da.SelectCommand = cmd;
DataSet ds = new DataSet();
try
{
da.Fill(ds, "ds");
cmd.Parameters.Clear();
}
catch (Exception ex)
{ }
return ds;
}
}
}
} /// <summary>
/// 执行查询语句,返回DataSet
/// </summary>
/// <param name="aSQLWithParameter">查询语句</param>
/// <returns>DataSet</returns>
public DataSet Query(SQLWithParameter aSQLWithParameter)
{
using (DbConnection conn = _DbFactory.CreateConnection())
{
conn.ConnectionString = mDBConfig.ConnString;
using (DbCommand cmd = _DbFactory.CreateCommand())
{
PrepareCommand(cmd, conn, aSQLWithParameter.SQL.ToString(), aSQLWithParameter.Parameters);
using (DbDataAdapter da = _DbFactory.CreateDataAdapter())
{
da.SelectCommand = cmd;
DataSet ds = new DataSet();
da.Fill(ds, "ds");
cmd.Parameters.Clear();
return ds;
}
}
}
}
#endregion #region 私有函数
private void PrepareCommand(DbCommand cmd, DbConnection conn, string cmdText)
{
if (conn.State != ConnectionState.Open)
conn.Open();
cmd.Connection = conn;
cmd.CommandText = cmdText;
} private void PrepareCommand(DbCommand cmd, DbConnection conn, string cmdText, List<DbParameter> cmdParms)
{
if (conn.State != ConnectionState.Open)
conn.Open();
cmd.Connection = conn;
cmd.CommandText = cmdText;
if (cmdParms != null && cmdParms.Count>)
{
cmd.Parameters.AddRange(cmdParms.ToArray());
}
}
#endregion
兼容SQLSERVER、Oracle、MYSQL、SQLITE的超级DBHelper的更多相关文章
- SQLServer Oracle MySQL的区别
table tr:nth-child(odd){ background: #FFFFCC; font-size: 18px; } table tr:nth-child(even){ backgroun ...
- sqlserver,oracle,mysql等的driver驱动,url怎么写
oracle driver="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@localhost:1521 ...
- SqlServer,Oracle,Mysql 获取指定行数
--sqlserver * FROM dbo.T_TASK --oracle --mysql ,
- 《物联网框架ServerSuperIO教程》-19.设备驱动和OPC Client支持mysql、oracle、sqlite、sqlserver的持久化。v3.6.4版本发布
19.设备驱动和OPC Client支持mysql.oracle.sqlite.sqlserver的持久化 19.1 概述 ServerSuperIO支持设备驱动和OPC Client采集的数 ...
- c#几种数据库的大数据批量插入(SqlServer、Oracle、SQLite和MySql)
这篇文章主要介绍了c#几种数据库的大数据批量插入(SqlServer.Oracle.SQLite和MySql),需要的朋友可以了解一下. 在之前只知道SqlServer支持数据批量插入,殊不知道Ora ...
- 你搞懂 ORACLE、 SQLSERVER、MYSQL与DB2的区别了吗
ORACLE. SQLSERVER.MYSQL与DB2的区别--平台性: Oracle.MYSQL与DB2可在所有主流平台上运行: SQL Server只能在Windows下运行: --安 ...
- <<< sqlserver、Mysql、Oracle数据库优缺点
sqlserver 优点: 易用性.适合分布式组织的可伸缩性.用于决策支持的数据仓库功能.与许多其他服务器软件紧密关联的集成性.良好的性价比等: 为数据管理与分析带来了灵活性,允许单位在快速变化的 ...
- Oracle/Mysql/SqlServer函数区别
mysql日期和时间格式转换 Linux scp 使用详解 Oracle/Mysql/SqlServer函数区别 2011-07-01 12:34:36| 分类: Mysql技术 | 标签:mys ...
- sqlserver、mysql、oracle各自的默认端口号
sqlserver默认端口号为:1433 URL:"jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=dbname" D ...
随机推荐
- .NET Core的文件系统[5]:扩展文件系统构建一个简易版“云盘”
FileProvider构建了一个抽象文件系统,作为它的两个具体实现,PhysicalFileProvider和EmbeddedFileProvider则分别为我们构建了一个物理文件系统和程序集内嵌文 ...
- 关于python的bottle框架跨域请求报错问题的处理
在用python的bottle框架开发时,前端使用ajax跨域访问时,js代码老是进入不了success,而是进入了error,而返回的状态却是200.url直接在浏览器访问也是正常的,浏览器按F12 ...
- ubuntu如何安装nodejs最新版 本
如何正确的安装nodejs? 我们可以先安装nvm, git clone https://github.com/creationix/nvm.git ~/.nvm 然后打开 ~/.bashrc , ...
- 深入理解DOM节点操作
× 目录 [1]创建节点 [2]插入节点 [3]移除节点[4]替换节点[5]复制节点 前面的话 一般地,提起操作会想到“增删改查”这四个字,而DOM节点操作也类似地对应于此,接下来将详细介绍DOM的节 ...
- xss和sql注入原理学习
8.4 Web跨站脚本攻击 8.4.1 跨站脚本攻击的原理(1) 跨站脚本在英文中称为Cross-Site Scripting,缩写为CSS.但是,由于层叠样式表 (Cascading Style ...
- jenkins无法重启tomcat的原因
在使用Hudson的执行sh脚本的时候,如果sh脚本是一个后台进程,如 Tomcat 这样的服务.如果使用Hudson的默认配置,会发现这些sh 进程有启动的过程,但是不会常驻后台,看Hudson 输 ...
- nginx代理https站点(亲测)
nginx代理https站点(亲测) 首先,我相信大家已经搞定了nginx正常代理http站点的方法,下面重点介绍代理https站点的配置方法,以及注意事项,因为目前大部分站点有转换https的需要所 ...
- CentOS下Zabbix安装部署及汉化
搭建环境:Centos6.5_x86_64,Zabbix2.4.5,epel 源 服务端: 1.安装开发软件包yum -y groupinstall "Development Tools&q ...
- <程序员从入门到精通> -- How
定位 自己才是职业生涯的管理者,想清楚自己的发展路径: 远期的理想是什么?近期的规划是什么?今日的任务和功课又是什么? 今日之任务或功课哪些有助于近期之规划的实现,而近期之规划是否有利于远期之理想? ...
- Linux学习日记-(一)
一.为什么学习Linux 大学时开始接触Linux,最开始学习的是RedHat(小红帽),感觉Linux好像很久不见的老朋友,用起来很舒服(虽然我们用的是DotNet).很喜欢它的命令模式,让我能接触 ...