兼容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 ...
随机推荐
- 谈谈一些有趣的CSS题目(八)-- 纯CSS的导航栏Tab切换方案
开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...
- C#多线程之线程同步篇2
在上一篇C#多线程之线程同步篇1中,我们主要学习了执行基本的原子操作.使用Mutex构造以及SemaphoreSlim构造,在这一篇中我们主要学习如何使用AutoResetEvent构造.Manual ...
- .NET同步与异步之相关背景知识(六)
在之前的五篇随笔中,已经介绍了.NET 类库中实现并行的常见方式及其基本用法,当然.这些基本用法远远不能覆盖所有,也只能作为一个引子出现在这里.以下是前五篇随笔的目录: .NET 同步与异步之封装成T ...
- Nginx学习笔记--001-Nginx快速搭建
Nginx ("engine x") 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器.Nginx是由Igor Sysoev为俄罗斯访问量第二的R ...
- ExecuteOrDelayUntilScriptLoaded 还是 SP.SOD.executeFunc?
SharePoint 客户端 JS 开发时,要等待 SharePoint 对象都加载完毕再调用自己的方法(myFunction),可以有两种方式: ExecuteOrDelayUntilScriptL ...
- 如何开发FineReport的自定义控件?
FineReport作为插件化开发的报表软件,有些特殊需求的功能需要自己开发,开发的插件包帆软官方有提提供,可以去帆软论坛上找,本文将主要介绍如何开发一个自定义控件,这里讲讲方法论. 第一步:实例化一 ...
- Tomcat之APR错误
在发布Apache Tomcat的时候,突然出现如下错误: An incompatible version 1.1.31 of the APR based Apache Tomcat Native l ...
- SpringMVC初步
SpringMVC框架介绍 1) Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面. Spring 框架提供了构建 Web 应用程序的全功 ...
- 如何让spring mvc web应用启动时就执行特定处理
Asp.Net的应用中通过根目录下的Global.asax,在Application_Start方法中做一些初始化操作,比如:预先加载缓存项对网站热点数据进行预热,获取一些远程的配置信息等等. Spr ...
- 从Maya中把模型搬运至网页的过程
虽然利用threejs来在网页中渲染3d模型不是第一次折腾了,但是还是遇到了各种问题.总结下我所遇到的问题,希望能给正在使用threejs的小伙伴一个帮助. 一.所使用的软件与开发环境 Maya201 ...