兼容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 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...
- 引人瞩目的 CSS 变量(CSS Variable)
这是一个令人激动的革新. CSS 变量,顾名思义,也就是由网页的作者或用户定义的实体,用来指定文档中的特定变量. 更准确的说法,应该称之为 CSS 自定义属性 ,不过下文为了好理解都称之为 CSS 变 ...
- 免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)
在生活中有一种东西几乎已经快要成为我们的另一个电子”身份证“,那就是二维码.无论是在软件开发的过程中,还是在普通用户的日常中,几乎都离不开二维码.二维码 (dimensional barcode) , ...
- 常用 meta 整理
<!-- 针对手持设备优化,主要是针对一些老的不识别viewport的浏览器,比如黑莓 --> <meta name="HandheldFriendly" con ...
- 浅谈Web自适应
前言 随着移动设备的普及,移动web在前端工程师们的工作中占有越来越重要的位置.移动设备更新速度频繁,手机厂商繁多,导致的问题是每一台机器的屏幕宽度和分辨率不一样.这给我们在编写前端界面时增加了困难, ...
- A/B Testing的简要知识
A/B testing主要用来检测网站或者APP的两个版本中哪一个更好,它的中心思想是把流量一分为二,一份用作experiment group,访问新的版本,另一份用作control group,访问 ...
- vim+vundle配置
Linux环境下写代码虽然没有IDE,但通过给vim配置几个插件也足够好用.一般常用的插件主要包括几类,查找文件,查找符号的定义或者声明(函数,变量等)以及自动补全功能.一般流程都是下载需要的工具,然 ...
- fmt标签把时间戳格式化日期
jsp页面标签格式化日期 <%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="f" %> ...
- 简单的转盘抽奖——CSS动画优化
前言 前两天去一家公司面试,被问到一些小游戏的东西.面试官提到了刷红包还有抽奖这些怎么实现,当时简单说了下思路,回来之后想想还是说的太轻描淡写了,干说不做就是耍流氓,所以就做了一个(Demo & ...
- WPF自定义控件第一 - 进度条控件
本文主要针对WPF新手,高手可以直接忽略,更希望高手们能给出一些更好的实现思路. 前期一个小任务需要实现一个类似含步骤进度条的控件.虽然对于XAML的了解还不是足够深入,还是摸索着做了一个.这篇文章介 ...