分享

强大的数据库操作类DBHelper

 丰收书屋 2017-09-11

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

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



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

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

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

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

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约