本示例代码的关键是利用.net库自带的DbProviderFactory来生产数据库操作对象。

从下图中,可以看到其的多个核心方法,这些方法将在我们的超级DBHelper中使用。

仔细研究,你会发现每个数据库的官方支持dll都有一个Instance对象,这个对象都是继承了DbProviderFactory了。

因此利用这点,我们就可以实现兼容多种数据的超级DBHelper了。

以下为示例代码,仅供参考学习,代码只是我的ORM框架中的一个片段(其中暂时支持了SQLSERVER、MySQL、SQLITE三种数据库,LoadDbProviderFactory方法是将封装在dll中的数据库操作dll反射加载实例化的方法。):

  1. /// <summary>
  2. /// 超级数据库操作类
  3. /// <para>2015年12月21日</para>
  4. /// </summary>
  5. public class DBHelper
  6. {
  7. #region 属性
  8. private DbProviderFactory _DbFactory;
  9. private DBConfig mDBConfig;
  10.  
  11. /// <summary>
  12. /// 数据库连接配置
  13. /// </summary>
  14. public DBConfig DBConfig
  15. {
  16. get { return mDBConfig; }
  17. }
  18.  
  19. /// <summary>
  20. /// 表示一组方法,这些方法用于创建提供程序对数据源类的实现的实例。
  21. /// </summary>
  22. public DbProviderFactory DbFactory
  23. {
  24. get { return _DbFactory; }
  25. set { _DbFactory = value; }
  26. }
  27. #endregion
  28.  
  29. #region 构造函数
  30. public DBHelper(DBConfig aORMConfig)
  31. {
  32. mDBConfig = aORMConfig;
  33. switch (mDBConfig.DBType)
  34. {
  35. case ORMType.DBTypes.SQLSERVER:
  36. _DbFactory = System.Data.SqlClient.SqlClientFactory.Instance;
  37. break;
  38. case ORMType.DBTypes.MYSQL:
  39. LoadDbProviderFactory("MySql.Data.dll", "MySql.Data.MySqlClient.MySqlClientFactory");
  40. break;
  41. case ORMType.DBTypes.SQLITE:
  42. LoadDbProviderFactory("System.Data.SQLite.dll", "System.Data.SQLite.SQLiteFactory");
  43. break;
  44. }
  45. }
  46.  
  47. /// <summary>
  48. /// 动态载入数据库封装库
  49. /// </summary>
  50. /// <param name="aDLLName">数据库封装库文件名称</param>
  51. /// <param name="aFactoryName">工厂路径名称</param>
  52. private void LoadDbProviderFactory(string aDLLName, string aFactoryName)
  53. {
  54. string dllPath = string.Empty;
  55. if (System.AppDomain.CurrentDomain.RelativeSearchPath != null)
  56. {
  57. dllPath = System.AppDomain.CurrentDomain.RelativeSearchPath+"\\"+ aDLLName;
  58. }
  59. else
  60. {
  61. dllPath = System.AppDomain.CurrentDomain.BaseDirectory + aDLLName;
  62. }
  63. if (!File.Exists(dllPath))
  64. {//文件不存在,从库资源中复制输出到基目录下
  65. FileStream fdllFile = new FileStream(dllPath,FileMode.Create);
  66. byte[] dllData = null;
  67. if (aDLLName == "System.Data.SQLite.dll")
  68. {
  69. dllData = YFmk.ORM.Properties.Resources.System_Data_SQLite;
  70. }
  71. else if (aDLLName == "MySql.Data.dll")
  72. {
  73. dllData = YFmk.ORM.Properties.Resources.MySql_Data;
  74. }
  75. fdllFile.Write(dllData, , dllData.Length);
  76. fdllFile.Close();
  77. }
  78. Assembly libAssembly = Assembly.LoadFile(dllPath);
  79. Type type = libAssembly.GetType(aFactoryName);
  80. foreach (FieldInfo fi in type.GetFields(BindingFlags.Static | BindingFlags.Public))
  81. {
  82. if (fi.Name == "Instance")
  83. {
  84. _DbFactory = fi.GetValue(null) as DbProviderFactory;
  85. return;
  86. }
  87. }
  88. }
  89. #endregion
  90.  
  91. #region 数据库操作
  92. /// <summary>
  93. /// 执行一条计算查询结果语句,返回查询结果
  94. /// </summary>
  95. /// <param name="aSQLWithParameter">SQL语句及参数</param>
  96. /// <returns>查询结果(object)</returns>
  97. public object GetSingle(SQLWithParameter aSQLWithParameter)
  98. {
  99. using (DbConnection conn = _DbFactory.CreateConnection())
  100. {
  101. conn.ConnectionString = mDBConfig.ConnString;
  102. using (DbCommand cmd = _DbFactory.CreateCommand())
  103. {
  104. PrepareCommand(cmd, conn, aSQLWithParameter.SQL.ToString(), aSQLWithParameter.Parameters);
  105. object obj = cmd.ExecuteScalar();
  106. cmd.Parameters.Clear();
  107. if ((Object.Equals(obj, null)) || (Object.Equals(obj, System.DBNull.Value)))
  108. {
  109. return null;
  110. }
  111. else
  112. {
  113. return obj;
  114. }
  115. }
  116. }
  117. }
  118.  
  119. /// <summary>
  120. /// 执行SQL语句,返回影响的记录数
  121. /// </summary>
  122. /// <param name="aSQL">SQL语句</param>
  123. /// <returns>影响的记录数</returns>
  124. public int ExecuteSql(string aSQL)
  125. {
  126. using (DbConnection conn = _DbFactory.CreateConnection())
  127. {
  128. conn.ConnectionString = mDBConfig.ConnString;
  129. using (DbCommand cmd = _DbFactory.CreateCommand())
  130. {
  131. PrepareCommand(cmd, conn, aSQL);
  132. int rows = cmd.ExecuteNonQuery();
  133. cmd.Parameters.Clear();
  134. return rows;
  135. }
  136. }
  137. }
  138.  
  139. /// <summary>
  140. /// 执行SQL语句,返回影响的记录数
  141. /// </summary>
  142. /// <param name="aSQLWithParameter">SQL语句及参数</param>
  143. /// <returns></returns>
  144. public int ExecuteSql(SQLWithParameter aSQLWithParameter)
  145. {
  146. using (DbConnection conn = _DbFactory.CreateConnection())
  147. {
  148. conn.ConnectionString = mDBConfig.ConnString;
  149. using (DbCommand cmd = _DbFactory.CreateCommand())
  150. {
  151. PrepareCommand(cmd, conn, aSQLWithParameter.SQL.ToString(), aSQLWithParameter.Parameters);
  152. int rows = cmd.ExecuteNonQuery();
  153. cmd.Parameters.Clear();
  154. return rows;
  155. }
  156. }
  157. }
  158.  
  159. /// <summary>
  160. /// 执行多条SQL语句,实现数据库事务。
  161. /// </summary>
  162. /// <param name="aSQLWithParameterList">参数化的SQL语句结构体对象集合</param>
  163. public string ExecuteSqlTran(List<SQLWithParameter> aSQLWithParameterList)
  164. {
  165. using (DbConnection conn = _DbFactory.CreateConnection())
  166. {
  167. conn.ConnectionString = mDBConfig.ConnString;
  168. conn.Open();
  169. DbTransaction fSqlTransaction = conn.BeginTransaction();
  170. try
  171. {
  172. List<DbCommand> fTranCmdList = new List<DbCommand>();
  173. //创建新的CMD
  174. DbCommand fFirstCMD = _DbFactory.CreateCommand();
  175. fFirstCMD.Connection = conn;
  176. fFirstCMD.Transaction = fSqlTransaction;
  177. fTranCmdList.Add(fFirstCMD);
  178. int NowCmdIndex = ;//当前执行的CMD索引值
  179. int ExecuteCount = ;//已经执行的CMD次数
  180. StringBuilder fSQL = new StringBuilder();
  181. foreach (SQLWithParameter fSQLWithParameter in aSQLWithParameterList)
  182. {
  183. fSQL.Append(fSQLWithParameter.SQL.ToString() + ";");
  184. fTranCmdList[NowCmdIndex].Parameters.AddRange(fSQLWithParameter.Parameters.ToArray());
  185. if (fTranCmdList[NowCmdIndex].Parameters.Count > )
  186. { //参数达到2000个,执行一次CMD
  187. fTranCmdList[NowCmdIndex].CommandText = fSQL.ToString();
  188. fTranCmdList[NowCmdIndex].ExecuteNonQuery();
  189. DbCommand fNewCMD = _DbFactory.CreateCommand();
  190. fNewCMD.Connection = conn;
  191. fNewCMD.Transaction = fSqlTransaction;
  192. fTranCmdList.Add(fNewCMD);
  193. NowCmdIndex++;
  194. ExecuteCount++;
  195. fSQL.Clear();//清空SQL
  196. }
  197. }
  198. if (ExecuteCount < fTranCmdList.Count)
  199. {//已执行CMD次数小于总CMD数,执行最后一条CMD
  200. fTranCmdList[fTranCmdList.Count - ].CommandText = fSQL.ToString();
  201. fTranCmdList[fTranCmdList.Count - ].ExecuteNonQuery();
  202. }
  203. fSqlTransaction.Commit();
  204. return null;
  205. }
  206. catch (Exception ex)
  207. {
  208. fSqlTransaction.Rollback();
  209. StringBuilder fSQL = new StringBuilder();
  210. foreach (SQLWithParameter fSQLWithParameter in aSQLWithParameterList)
  211. {
  212. fSQL.Append(fSQLWithParameter.SQL.ToString() + ";");
  213. }
  214. YFmk.Lib.LocalLog.WriteByDate(fSQL.ToString()+" 错误:"+ex.Message, "ORM");
  215. return ex.Message;
  216. }
  217. }
  218. }
  219.  
  220. /// <summary>
  221. /// 执行查询语句,返回DataSet
  222. /// </summary>
  223. /// <param name="SQLString">查询语句</param>
  224. /// <returns>DataSet</returns>
  225. public DataSet Query(string SQLString)
  226. {
  227. using (DbConnection conn = _DbFactory.CreateConnection())
  228. {
  229. conn.ConnectionString = mDBConfig.ConnString;
  230. using (DbCommand cmd = _DbFactory.CreateCommand())
  231. {
  232. PrepareCommand(cmd, conn, SQLString);
  233. using (DbDataAdapter da = _DbFactory.CreateDataAdapter())
  234. {
  235. da.SelectCommand = cmd;
  236. DataSet ds = new DataSet();
  237. try
  238. {
  239. da.Fill(ds, "ds");
  240. cmd.Parameters.Clear();
  241. }
  242. catch (Exception ex)
  243. {
  244.  
  245. }
  246. return ds;
  247. }
  248. }
  249. }
  250. }
  251.  
  252. /// <summary>
  253. /// 执行查询语句,返回DataSet
  254. /// </summary>
  255. /// <param name="aSQLWithParameter">查询语句</param>
  256. /// <returns>DataSet</returns>
  257. public DataSet Query(SQLWithParameter aSQLWithParameter)
  258. {
  259. using (DbConnection conn = _DbFactory.CreateConnection())
  260. {
  261. conn.ConnectionString = mDBConfig.ConnString;
  262. using (DbCommand cmd = _DbFactory.CreateCommand())
  263. {
  264. PrepareCommand(cmd, conn, aSQLWithParameter.SQL.ToString(), aSQLWithParameter.Parameters);
  265. using (DbDataAdapter da = _DbFactory.CreateDataAdapter())
  266. {
  267. da.SelectCommand = cmd;
  268. DataSet ds = new DataSet();
  269. da.Fill(ds, "ds");
  270. cmd.Parameters.Clear();
  271. return ds;
  272. }
  273. }
  274. }
  275. }
  276. #endregion
  277.  
  278. #region 私有函数
  279. private void PrepareCommand(DbCommand cmd, DbConnection conn, string cmdText)
  280. {
  281. if (conn.State != ConnectionState.Open)
  282. conn.Open();
  283. cmd.Connection = conn;
  284. cmd.CommandText = cmdText;
  285. }
  286.  
  287. private void PrepareCommand(DbCommand cmd, DbConnection conn, string cmdText, List<DbParameter> cmdParms)
  288. {
  289. if (conn.State != ConnectionState.Open)
  290. conn.Open();
  291. cmd.Connection = conn;
  292. cmd.CommandText = cmdText;
  293. if (cmdParms != null && cmdParms.Count>)
  294. {
  295. cmd.Parameters.AddRange(cmdParms.ToArray());
  296. }
  297. }
  298. #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. 谈谈一些有趣的CSS题目(六)-- 全兼容的多列均匀布局问题

    开本系列,谈谈一些有趣的 CSS 题目,题目类型天马行空,想到什么说什么,不仅为了拓宽一下解决问题的思路,更涉及一些容易忽视的 CSS 细节. 解题不考虑兼容性,题目天马行空,想到什么说什么,如果解题 ...

  2. 引人瞩目的 CSS 变量(CSS Variable)

    这是一个令人激动的革新. CSS 变量,顾名思义,也就是由网页的作者或用户定义的实体,用来指定文档中的特定变量. 更准确的说法,应该称之为 CSS 自定义属性 ,不过下文为了好理解都称之为 CSS 变 ...

  3. 免费开源的DotNet二维码操作组件ThoughtWorks.QRCode(.NET组件介绍之四)

    在生活中有一种东西几乎已经快要成为我们的另一个电子”身份证“,那就是二维码.无论是在软件开发的过程中,还是在普通用户的日常中,几乎都离不开二维码.二维码 (dimensional barcode) , ...

  4. 常用 meta 整理

    <!-- 针对手持设备优化,主要是针对一些老的不识别viewport的浏览器,比如黑莓 --> <meta name="HandheldFriendly" con ...

  5. 浅谈Web自适应

    前言 随着移动设备的普及,移动web在前端工程师们的工作中占有越来越重要的位置.移动设备更新速度频繁,手机厂商繁多,导致的问题是每一台机器的屏幕宽度和分辨率不一样.这给我们在编写前端界面时增加了困难, ...

  6. A/B Testing的简要知识

    A/B testing主要用来检测网站或者APP的两个版本中哪一个更好,它的中心思想是把流量一分为二,一份用作experiment group,访问新的版本,另一份用作control group,访问 ...

  7. vim+vundle配置

    Linux环境下写代码虽然没有IDE,但通过给vim配置几个插件也足够好用.一般常用的插件主要包括几类,查找文件,查找符号的定义或者声明(函数,变量等)以及自动补全功能.一般流程都是下载需要的工具,然 ...

  8. fmt标签把时间戳格式化日期

    jsp页面标签格式化日期 <%@taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="f" %> ...

  9. 简单的转盘抽奖——CSS动画优化

    前言 前两天去一家公司面试,被问到一些小游戏的东西.面试官提到了刷红包还有抽奖这些怎么实现,当时简单说了下思路,回来之后想想还是说的太轻描淡写了,干说不做就是耍流氓,所以就做了一个(Demo & ...

  10. WPF自定义控件第一 - 进度条控件

    本文主要针对WPF新手,高手可以直接忽略,更希望高手们能给出一些更好的实现思路. 前期一个小任务需要实现一个类似含步骤进度条的控件.虽然对于XAML的了解还不是足够深入,还是摸索着做了一个.这篇文章介 ...