• 学习之路十六:自定义数据库通用类 → 模仿+改进


    这段时间参考了公司封装的数据库类库,感觉挺新奇了,从中学到了一些新的知识,有配置文件,有通过反射获得实例名,单例模式等等,这篇算是一个总结把,分享一些我的感受~~

    一丶主要关系图

    二丶自定义配置文件节点

      通过这种方式可以自定义节点,而不需要系统提供的key和value来存储数据库连接字符串!

      而且自定义节点算是比较简单的,主要弄懂一些继承关系就OK了...

      Note:在定义节点的时候要注意一些主从关系,也就是Section,Element,ElementCollection之间的关系!

      一个Section下面可能有很多的Element,一个Element下面可能有很多的Element集合,如:

      <appSettings> <!--Element-->
        <add key="" value=""/> <!--ElementCollection-->
        <add key="" value=""/> <!--可以存在多个add-->
        <add key="" value=""/>
      </appSettings>

      在写代码之前先要熟悉ConfigurationSection,ConfigurationElement,ConfigurationElementCollection,下面三个基类对应这上面说的三者关系,理解他们写代码就容易多了,代码如下:

      1.首先定义Section  

        public class DBAccessBrokerSection : ConfigurationSection
        {
            [ConfigurationProperty("DBAccess")]  //定义Section下面有多少个Element,可以是单个Element,也可以是ElementCollection
            public DBAccessElement DBAccess
            {
                get
                {
                    return (DBAccessElement)base["DBAccess"];
                }
            }
    
            [ConfigurationProperty("DBConnections")]  //注意这个特性的用法,它对应这配置文件中的具体写法
            public DBConnectionCollection DBConnections
            {
                get
                {
                    return (DBConnectionCollection)base["DBConnections"];
                }
            }
        }

      2.定义单个Element 

     1     public class DBAccessElement : ConfigurationElement
     2     {
     3         [ConfigurationProperty("Namespace", IsKey = true, IsRequired = true)]
     4         public string Namespace
     5         {
     6             get
     7             {
     8                 return (string)base["Namespace"];
     9             }
    10             set
    11             {
    12                 base["Namespace"] = value;
    13             }
    14         }
    15 
    16         [ConfigurationProperty("FullName", DefaultValue = "", IsKey = false, IsRequired = false)]
    17         public string FullName
    18         {
    19             get
    20             {
    21                 return (string)base["FullName"];
    22             }
    23             set
    24             {
    25                 base["FullName"] = value;
    26             }
    27         }
    28     }

      3.定义ElementCollection

      Note:主要要把ElementCollection和单个Element关联起来,因为ElementCollection也是由单个Element组合起来,所以这点很重要!

    View Code
     1     public class DBConnectionElement : ConfigurationElement
     2     {
     3         [ConfigurationProperty("ConnectionString", IsKey = false, IsRequired = false)]
     4         public string ConnectionString
     5         {
     6             get
     7             {
     8                 return (string)base["ConnectionString"];
     9             }
    10             set
    11             {
    12                 base["ConnectionString"] = value;
    13             }
    14         }
    15     }
    16 
    17     [ConfigurationCollection(typeof(DBConnectionElement))]
    18     public class DBConnectionCollection : ConfigurationElementCollection  //注意继承关系
    19     {
    20         protected override ConfigurationElement CreateNewElement()  //重载基类中的方法
    21         {
    22             return new DBConnectionElement();
    23         }
    24 
    25         protected override object GetElementKey(ConfigurationElement element)
    26         {
    27             return ((DBConnectionElement)element).ConnectionString;
    28         }
    29 
    30         public DBConnectionElement this[int index]
    31         {
    32             get
    33             {
    34                 return (DBConnectionElement)BaseGet(index);
    35             }
    36         }
    37     }

        4.最终在配置文件中的形式如下

    1   <DBAccessBroker>  //Section
    2     <DBAccess FullName="类的完全限定名" Namespace ="填写命名空间"/>  //Element
    3     <DBConnections>  //ElementCollection
    4       <add ConnectionString=""/> <!--这是伪代码-->
    5       <add ConnectionString=""/> //Elemetnt,这边属性不只有ConnectionString一个,还可以定义很多,这边只是写的伪代码
    6       <add ConnectionString=""/>
    7     </DBConnections>
    8   </DBAccessBroker>

      参考:创建自定义配置节点(web.config和app.config都适用) 

     三丶通过单例实现只有一个实例,通过反射动态获取实例名

     1     public sealed class DBBrokerManager
     2     {
     3         private static DBAccessBroker _accessBroke = null;
     4         private static object _obj = new object();
     5 
     6         private DBBrokerManager() { }
     7 
     8         static DBBrokerManager() { }
     9 
    10         public static DBAccessBroker CurrentBroker
    11         {
    12             get
    13             {
    14                 if (_accessBroke == null)
    15                 {
    16                     lock (_obj)
    17                     {
    18                         if (_accessBroke == null)
    19                         {
    20                             _accessBroke = new DBAccessBroker(GenerateDBAccessFromConfiguration(), GenerateDBConnectionsFromConfiguration());
    21                             return _accessBroke;
    22                         }
    23                     }
    24                 }
    25                 return _accessBroke;
    26             }
    27         }
    28 
    29         private static IDBAccess GenerateDBAccessFromConfiguration()  //通过反射获取实例对象
    30         {
    31             try
    32             {
    33                 DBAccessBrokerSection section = (DBAccessBrokerSection)ConfigurationManager.GetSection("DBAccessBroker");
    34                 IDBAccess dbAccess = (IDBAccess)Assembly.Load(section.DBAccess.Namespace).CreateInstance(section.DBAccess.FullName);
    35                 return dbAccess;
    36             }
    37             catch (ConfigurationException configurationException)
    38             {
    39                 LoggingManager.WriteLog(LogLevel.Exception, configurationException.Message, configurationException.InnerException);
    40                 return null;
    41             }
    42             catch (Exception exception)
    43             {
    44                 LoggingManager.WriteLog(LogLevel.Exception, exception.Message, exception.InnerException);
    45                 return null;
    46             }
    47         }
    48 
    49         private static IList<DBConnectionInfo> GenerateDBConnectionsFromConfiguration()  //通过反射获取具体的连接字符串信息,这要根据项目有所变化了
    50         {
    51             try
    52             {
    53                 List<DBConnectionInfo> connectionInfoList = new List<DBConnectionInfo>();
    54                 DBAccessBrokerSection section = (DBAccessBrokerSection)ConfigurationManager.GetSection("DBAccessBroker");
    55                 foreach (DBConnectionElement element in section.DBConnections)
    56                 {
    57                     DBConnectionInfo connectionInfo = (DBConnectionInfo)Assembly.Load(section.DBAccess.Namespace).CreateInstance(section.DBAccess.Namespace + ".DBConnectionInfo");
    58                     foreach (PropertyInfo peopertyInfo in connectionInfo.GetType().GetProperties())
    59                     {
    60                         peopertyInfo.SetValue(connectionInfo, element.GetType().GetProperty(peopertyInfo.Name).GetValue(element, null), null);
    61                     }
    62                     connectionInfoList.Add(connectionInfo);
    63                 }
    64                 return connectionInfoList;
    65             }
    66             catch (ConfigurationException configurationException)
    67             {
    68                 LoggingManager.WriteLog(LogLevel.Exception, configurationException.Message, configurationException.InnerException);
    69                 return null;
    70             }
    71             catch (Exception exception)
    72             {
    73                 LoggingManager.WriteLog(LogLevel.Exception, exception.Message, exception.InnerException);
    74                 return null;
    75             }
    76         }
    77     }

      单例请参考:别再让面试官问你单例(暨6种实现方式让你堵住面试官的嘴)  

    四丶定义实现数据库操作的接口,用两个类来实现它,一个做中间过渡,一个是底层调用

      Note:(其实在很多项目中这个中间过渡是不需要的,但这个要根据具体的项目来变化)。

      1.接口定义

        public interface IDBAccess
        {
            void SetConnectionInfo(DBConnectionInfo connectionInfo);
    
            int ExecuteNonQuery(CommandType commandType, string commandText, params SqlParameter[] parameters);
    
            int ExecuteNonQueryWithTrans(CommandType commandType, string commandText, params SqlParameter[] parameters);
    
            DbDataReader ExecuteReader(CommandType commandType, string commandText, params SqlParameter[] parameters);
    
            object ExecuteScalar(CommandType commandType, string commandText, params SqlParameter[] parameters);
    
            DataTable ExecuteDataTable(CommandType commandType, string commandText, string tableName);
    
            DataTable ExecuteDataTable(CommandType commandType, string commandText, string tableName, params SqlParameter[] parameters);
        }

      2.两个类同时实现这个接口,一个做过渡,一个做底层调用

      2.1 过渡类

    View Code
     1     public class DBAccessBroker : IDBAccess
     2     {
     3         private IDBAccess _dbAccess;
     4         private IList<DBConnectionInfo> _connectionInfoList;
     5         private DBConnectionInfo _localConnection;
     6         private DBConnectionInfo _serverConnection;
     7 
     8         public DBAccessBroker(IDBAccess dbAccess, IList<DBConnectionInfo> connectionInfoList)
     9         {
    10             _dbAccess = dbAccess;
    11             _connectionInfoList = connectionInfoList;
    12             _serverConnection = (from connectionInfo in connectionInfoList where connectionInfo.IsServer == true select connectionInfo).ToList().FirstOrDefault();
    13             _localConnection = (from connectionInfo in connectionInfoList where connectionInfo.IsServer == false select connectionInfo).ToList().FirstOrDefault();
    14             if (_localConnection != null)
    15                 SetConnectionInfo(_localConnection);
    16         }
    17 
    18         #region IDBAccess Members
    19 
    20         public void SetConnectionInfo(DBConnectionInfo connectionInfo)
    21         {
    22             BaseUtils.Common common = new BaseUtils.Common();
    23             if (string.IsNullOrEmpty(connectionInfo.ConfigFile))
    24                 throw new Exception("XML configuration path is empty, please provides correct XML path. Please contact administrator for the errors.");
    25             if (string.IsNullOrEmpty(connectionInfo.SystemName))
    26                 throw new Exception("System Name is empty, please provides correct system name that configured in XML configuration file. Please contact administrator for the errors.");
    27             connectionInfo.ConnectionString = common.GetConnString(connectionInfo.ConfigFile, connectionInfo.SystemName, connectionInfo.IsConnStrEncrypted, connectionInfo.ConnStringNode);
    28             if (_dbAccess != null)
    29                 _dbAccess.SetConnectionInfo(connectionInfo);
    30         }
    31 
    32         public int ExecuteNonQuery(CommandType commandType, string commandText, params  SqlParameter[] parameters)
    33         {
    34             return _dbAccess.ExecuteNonQuery(commandType, commandText, null);
    35         }
    36 
    37         public int ExecuteNonQueryWithTrans(CommandType commandType, string commandText, params  SqlParameter[] parameters)
    38         {
    39             return _dbAccess.ExecuteNonQueryWithTrans(commandType, commandText, parameters);
    40         }
    41 
    42         public DbDataReader ExecuteReader(CommandType commandType, string commandText, params  SqlParameter[] parameters)
    43         {
    44             return _dbAccess.ExecuteReader(commandType, commandText, parameters);
    45         }
    46 
    47         public object ExecuteScalar(CommandType commandType, string commandText, params  SqlParameter[] parameters)
    48         {
    49             return _dbAccess.ExecuteScalar(commandType, commandText, parameters);
    50         }
    51 
    52         public DataTable ExecuteDataTable(CommandType commandType, string commandText, string tableName)
    53         {
    54             return _dbAccess.ExecuteDataTable(commandType, commandText, tableName);
    55         }
    56 
    57         public DataTable ExecuteDataTable(CommandType commandType, string commandText, string tableName, params  SqlParameter[] parameters)
    58         {
    59             return _dbAccess.ExecuteDataTable(commandType, commandText, tableName, parameters);
    60         }
    61 
    62         #endregion
    63     }

       2.2 底层调用类

    View Code
      1     public class SQLDBAccess : IDBAccess
      2     {
      3         private string _connectionString = string.Empty;
      4 
      5         #region IDBAccess Members
      6 
      7         public void SetConnectionInfo(DBConnectionInfo connectionInfo)
      8         {
      9             if (string.IsNullOrEmpty(connectionInfo.ConnectionString))
     10                 LoggingManager.WriteLog(LogLevel.Exception, "The connection string is null or empty.", "");
     11             else
     12                 _connectionString = connectionInfo.ConnectionString;
     13         }
     14 
     15         public int ExecuteNonQuery(CommandType commandType, string commandText, params SqlParameter[] parameters)
     16         {
     17             try
     18             {
     19                 using (SqlConnection connection = new SqlConnection(_connectionString))
     20                 {
     21                     connection.Open();
     22                     SqlCommand command = connection.CreateCommand();
     23                     command.CommandType = commandType;
     24                     command.CommandText = commandText;
     25                     if (parameters != null && parameters.Length > 0)
     26                         command.Parameters.AddRange(parameters);
     27                     return command.ExecuteNonQuery();
     28                 }
     29             }
     30             catch (SqlException sqlException)
     31             {
     32                 LoggingManager.WriteLog(LogLevel.Exception, sqlException.Message, sqlException.InnerException);
     33                 return 0;
     34             }
     35             catch (Exception exception)
     36             {
     37                 LoggingManager.WriteLog(LogLevel.Exception, exception.Message, exception.InnerException);
     38                 return 0;
     39             }
     40         }
     41 
     42         public int ExecuteNonQueryWithTrans(CommandType commandType, string commandText, params SqlParameter[] parameters)
     43         {
     44             try
     45             {
     46                 using (SqlConnection connection = new SqlConnection(_connectionString))
     47                 {
     48                     connection.Open();
     49                     SqlTransaction transaction = connection.BeginTransaction("Transaction");
     50                     try
     51                     {
     52                         SqlCommand command = connection.CreateCommand();
     53                         command.CommandType = commandType;
     54                         command.CommandText = commandText;
     55                         command.Transaction = transaction;
     56                         if (parameters != null && parameters.Length > 0)
     57                             command.Parameters.AddRange(parameters);
     58                         int result = command.ExecuteNonQuery();
     59                         transaction.Commit();
     60                         return result;
     61                     }
     62                     catch (Exception executeException)
     63                     {
     64                         transaction.Rollback();
     65                         connection.Close();
     66                         LoggingManager.WriteLog(LogLevel.Exception, executeException.Message, executeException.InnerException);
     67                         return 0;
     68                     }
     69                 }
     70             }
     71             catch (SqlException sqlException)
     72             {
     73                 LoggingManager.WriteLog(LogLevel.Exception, sqlException.Message, sqlException.InnerException);
     74                 return 0;
     75             }
     76             catch (Exception exception)
     77             {
     78                 LoggingManager.WriteLog(LogLevel.Exception, exception.Message, exception.InnerException);
     79                 return 0;
     80             }
     81         }
     82 
     83         public DbDataReader ExecuteReader(CommandType commandType, string commandText, params SqlParameter[] parameters)
     84         {
     85             try
     86             {
     87                 using (SqlConnection connection = new SqlConnection(_connectionString))
     88                 {
     89                     connection.Open();
     90                     SqlCommand command = connection.CreateCommand();
     91                     command.CommandType = commandType;
     92                     command.CommandText = commandText;
     93                     if (parameters != null && parameters.Length > 0)
     94                         command.Parameters.AddRange(parameters);
     95                     return command.ExecuteReader(CommandBehavior.CloseConnection);
     96                 }
     97             }
     98             catch (SqlException sqlException)
     99             {
    100                 LoggingManager.WriteLog(LogLevel.Exception, sqlException.Message, sqlException.InnerException.Message);
    101                 return null;
    102             }
    103             catch (Exception exception)
    104             {
    105                 LoggingManager.WriteLog(LogLevel.Exception, exception.Message, exception.InnerException.Message);
    106                 return null;
    107             }
    108         }
    109 
    110         public object ExecuteScalar(CommandType commandType, string commandText, params SqlParameter[] parameters)
    111         {
    112             try
    113             {
    114                 using (SqlConnection connection = new SqlConnection(_connectionString))
    115                 {
    116                     connection.Open();
    117                     SqlCommand command = connection.CreateCommand();
    118                     command.CommandType = commandType;
    119                     command.CommandText = commandText;
    120                     if (parameters != null && parameters.Length > 0)
    121                         command.Parameters.AddRange(parameters);
    122                     return command.ExecuteScalar();
    123                 }
    124             }
    125             catch (SqlException sqlException)
    126             {
    127                 LoggingManager.WriteLog(LogLevel.Exception, sqlException.Message, sqlException.InnerException);
    128                 return null;
    129             }
    130             catch (Exception exception)
    131             {
    132                 LoggingManager.WriteLog(LogLevel.Exception, exception.Message, exception.InnerException);
    133                 return null;
    134             }
    135         }
    136 
    137         public DataTable ExecuteDataTable(CommandType commandType, string commandText, string tableName)
    138         {
    139             return ExecuteDataTable(commandType, commandText, tableName, null);
    140         }
    141 
    142         public DataTable ExecuteDataTable(CommandType commandType, string commandText, string tableName, params SqlParameter[] parameters)
    143         {
    144             try
    145             {
    146                 using (SqlConnection connection = new SqlConnection(_connectionString))
    147                 {
    148                     connection.Open();
    149                     DataTable table = new DataTable(tableName);
    150                     SqlCommand command = connection.CreateCommand();
    151                     command.CommandType = commandType;
    152                     command.CommandText = commandText;
    153                     if (parameters != null && parameters.Length > 0)
    154                         command.Parameters.AddRange(parameters);
    155                     SqlDataAdapter adapter = new SqlDataAdapter(command);
    156                     adapter.Fill(table);
    157                     return table;
    158                 }
    159             }
    160             catch (SqlException sqlException)
    161             {
    162                 LoggingManager.WriteLog(LogLevel.Exception, sqlException.Message, sqlException.InnerException);
    163                 return null;
    164             }
    165             catch (Exception exception)
    166             {
    167                 LoggingManager.WriteLog(LogLevel.Exception, exception.Message, exception.InnerException);
    168                 return null;
    169             }
    170         }
    171 
    172         #endregion
    173     }

    五丶最后总结

      小菜在这里献丑了,代码里面还有需要完善的地方,如果园友们对代码有什么好的建议,请提出来我会虚心接受和请教的! 

      已同步至:程序猿个人文章目录索引

  • 相关阅读:
    EL表达式与JSTL
    JSP
    session
    四则运算 第二次
    第二次作业
    四则运算
    用户使用手册与测试报告
    系统设计和任务分配
    需求规格说明书和原型设计
    用户需求分析和竞品分析
  • 原文地址:https://www.cnblogs.com/yangcaogui/p/2640654.html
Copyright © 2020-2023  润新知