本示例代码的关键是利用.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的更多相关文章

  1. SQLServer Oracle MySQL的区别

    table tr:nth-child(odd){ background: #FFFFCC; font-size: 18px; } table tr:nth-child(even){ backgroun ...

  2. sqlserver,oracle,mysql等的driver驱动,url怎么写

    oracle driver="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@localhost:1521 ...

  3. SqlServer,Oracle,Mysql 获取指定行数

    --sqlserver * FROM dbo.T_TASK --oracle --mysql ,

  4. 《物联网框架ServerSuperIO教程》-19.设备驱动和OPC Client支持mysql、oracle、sqlite、sqlserver的持久化。v3.6.4版本发布

    19.设备驱动和OPC Client支持mysql.oracle.sqlite.sqlserver的持久化 19.1     概述 ServerSuperIO支持设备驱动和OPC Client采集的数 ...

  5. c#几种数据库的大数据批量插入(SqlServer、Oracle、SQLite和MySql)

    这篇文章主要介绍了c#几种数据库的大数据批量插入(SqlServer.Oracle.SQLite和MySql),需要的朋友可以了解一下. 在之前只知道SqlServer支持数据批量插入,殊不知道Ora ...

  6. 你搞懂 ORACLE、 SQLSERVER、MYSQL与DB2的区别了吗

    ORACLE. SQLSERVER.MYSQL与DB2的区别--平台性:    Oracle.MYSQL与DB2可在所有主流平台上运行:    SQL Server只能在Windows下运行: --安 ...

  7. <<< sqlserver、Mysql、Oracle数据库优缺点

    sqlserver 优点: 易用性.适合分布式组织的可伸缩性.用于决策支持的数据仓库功能.与许多其他服务器软件紧密关联的集成性.良好的性价比等:   为数据管理与分析带来了灵活性,允许单位在快速变化的 ...

  8. Oracle/Mysql/SqlServer函数区别

    mysql日期和时间格式转换 Linux scp 使用详解 Oracle/Mysql/SqlServer函数区别 2011-07-01 12:34:36|  分类: Mysql技术 |  标签:mys ...

  9. sqlserver、mysql、oracle各自的默认端口号

    sqlserver默认端口号为:1433 URL:"jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=dbname" D ...

随机推荐

  1. UWP开发之Mvvmlight实践七:如何查找设备(Mobile模拟器、实体手机、PC)中应用的Log等文件

    在开发中或者后期测试乃至最后交付使用的时候,如果应用出问题了我们一般的做法就是查看Log文件.上章也提到了查看Log文件,这章重点讲解下如何查看Log文件?如何找到我们需要的Packages安装包目录 ...

  2. Linux学习之探索文件系统

    Linux,一起学习进步-    ls With it, we can see directory contents and determine a variety of important file ...

  3. 如何将VCSA添加到微软域控环境,并且实现微软域账号登陆vCenter

    v:* { } o:* { } w:* { } .shape { } p.msonormal,li.msonormal,div.msonormal { margin: 0cm; margin-bott ...

  4. PHP设计模式(六)原型模式(Prototype For PHP)

    原型设计模式: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 原型设计模式简单的来说,顾名思义, 不去创建新的对象进而保留原型的一种设计模式. 缺点:原型设计模式是的最主要的缺点就 ...

  5. unity3d导出到IOS程序下 集成unity3dAR功能

    转载自: 来自AR学院(www.arvrschool.com),原文地址为:http://www.arvrschool.com/index.php?c=post&a=modify&ti ...

  6. Block解析(iOS)

    1. 操作系统中的栈和堆 我们先来看看一个由C/C++/OBJC编译的程序占用内存分布的结构: 栈区(stack):由系统自动分配,一般存放函数参数值.局部变量的值等.由编译器自动创建与释放.其操作方 ...

  7. Spring MVC入门

    1.什么是SpringMvc Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面.Spring 框架提供了构建 Web 应用程序的全功能 M ...

  8. java中判断字符串是否为只包含数字

    1.用Java自带的函数 public static boolean isNumeric(String str){ for(int i=str.length();--i>=0;){ if (!C ...

  9. DotNet Run 命令介绍

    前言 本篇主要介绍 asp.net core 中,使用 dotnet tools 运行 dotnet run 之后的系统执行过程. 如果你觉得对你有帮助的话,不妨点个[推荐]. 目录 dotnet r ...

  10. React单元测试——十八般兵器齐上阵,环境构建篇

    一个完整.优秀的项目往往离不开单元测试的环节,就 github 上的主流前端项目而言,基本都有相应的单元测试模块. 就 React 的项目来说,一套完整的单元测试能在在后续迭代更新中回归错误时候给与警 ...