Heim >Datenbank >MySQL-Tutorial >对数据访问层第一种实现(Acc+SQL)的重构

对数据访问层第一种实现(Acc+SQL)的重构

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOriginal
2016-06-07 15:11:121292Durchsuche

昨天的文章基于.NET平台的分层架构实战(七) 数据 访问 层的 第一 种 实现 :Access+SQL发布后,很多朋友对我的程序提出了意见和建议,在这里先谢谢你们!!!尤其是金色海洋(jyk),对我的程序提出了很多建设性的意见。 我大体总结了一下,昨天程序的主要

昨天的文章基于.NET平台的分层架构实战(七)——数据访问层的第一实现:Access+SQL发布后,很多朋友对我的程序提出了意见和建议,在这里先谢谢你们!!!尤其是 金色海洋(jyk),对我的程序提出了很多建设性的意见。

 我大体总结了一下,昨天程序的主要缺点有:
      1.Connection对象没有关闭
      2.DataReader对象没有关闭
      3.相似代码太多,造成代码冗余。

其中第一点问题,目前还没有太好的解决方案,主要是因为Connection一旦关闭,DataReader就无法读取了。而且,Connection对象应该会自动在适当的时候关闭(通过观察临时文件得出),并且在实际运行时并无影响(在功能上),所以这里没有专门解决。而针对后面两个问题,我使用了如下解决方案。

对于关闭DataReader的方法,实现起来很简单,在finally里将他关闭就行了。关键是如何去处冗余代码。

经过我的分析,数据访问层的操作可以分为三类:不返回数据,返回单个实体类,返回实体类集合。我将这三种操作的公共部分抽出,写成三个方法放在AccessDALHelper里,类型不同的问题使用泛型解决。

这样做有一个难题,就是不同实体在由DataReader转化为实体类时的代码很不一样,无法抽出。这里,我使用了Strategy模式解决。具体做法是:首先定义一个由DataReader转换为实体类的策略接口,然后为不同的实体编写不同的转换策略,示意图如下:

可以看出,所有转换策略都要实现IDataReaderToEntityStrategy接口,并且每个策略都有一个自组合,这是以为他们都要实现Singleton模式。而AccessDALHelper与具体策略无关,仅与接口耦合。

\

 

下面来看一下具体代码:

首先是IDataReaderToEntityStrategy接口

对数据访问层第一种实现(Acc+SQL)的重构IDataReaderToEntityStrategy
 1\using System;
 2\using System.Collections.Generic;
 3\using System.Text;
 4\using System.Data;
 5\using System.Data.OleDb;
 6\
 7\namespace NGuestBook.AccessDAL
 8\对数据访问层第一种实现(Acc+SQL)的重构\{
 9\对数据访问层第一种实现(Acc+SQL)的重构    /**//// 
10\    /// 由DataReader转换成实体类的策略接口
11\    /// 

12\    public interface IDataReaderToEntityStrategyT>
13\对数据访问层第一种实现(Acc+SQL)的重构    \{
14\对数据访问层第一种实现(Acc+SQL)的重构        /**//// 
15\        /// 将DataReader转换为实体类,采用泛型
16\        /// 
17\        /// 包含数据的DataReader对象
18\        /// 实体类

19\        T DataReaderToEntity(OleDbDataReader dataReader);
20\    }

21\}

然后以Admin为例,看一下策略的具体实现

1\using System;
  2\using System.Collections.Generic;
  3\using System.Web;
  4\using System.Web.Caching;
  5\using System.Configuration;
  6\using System.Data;
  7\using System.Data.OleDb;
  8\using NGuestBook.Utility;
  9\
 10\namespace NGuestBook.AccessDAL
 11\对数据访问层第一种实现(Acc+SQL)的重构\{
 12\对数据访问层第一种实现(Acc+SQL)的重构    /**//// 
 13\    /// Access数据库操作助手
 14\    /// 

 15\    public sealed class AccessDALHelper
 16\对数据访问层第一种实现(Acc+SQL)的重构    \{
 17\对数据访问层第一种实现(Acc+SQL)的重构        /**//// 
 18\        /// 读取Access数据库的连接字符串
 19\        /// 首先从缓存里读取,如果不存在则到配置文件中读取,并放入缓存
 20\        /// 
 21\        /// Access数据库的连接字符串

 22\        private static string GetConnectionString()
 23\对数据访问层第一种实现(Acc+SQL)的重构        \{
 24\            if (CacheAccess.GetFromCache("AccessConnectionString"!= null)
 25\对数据访问层第一种实现(Acc+SQL)的重构            \{
 26\                return CacheAccess.GetFromCache("AccessConnectionString").ToString();
 27\            }

 28\            else
 29\对数据访问层第一种实现(Acc+SQL)的重构            \{
 30\                string dbPath = ConfigurationManager.AppSettings["AccessPath"];
 31\                string dbAbsolutePath = HttpContext.Current.Server.MapPath(dbPath);
 32\                string connectionString = ConfigurationManager.AppSettings["AccessConnectionString"];
 33\
 34\                CacheDependency fileDependency = new CacheDependency(HttpContext.Current.Server.MapPath("Web.Config"));
 35\                CacheAccess.SaveToCache("AccessConnectionString", connectionString.Replace("{DBPath}", dbAbsolutePath), fileDependency);
 36\
 37\                return connectionString.Replace("{DBPath}", dbAbsolutePath);
 38\            }

 39\        }

 40\
 41\对数据访问层第一种实现(Acc+SQL)的重构        /**//// 
 42\        /// 执行SQL语句并且不返回任何值
 43\        /// 
 44\        /// 所执行的SQL命令
 45\        /// 参数集合

 46\        public static void ExecuteSQLNonQuery(string SQLCommand, OleDbParameter[] parameters)
 47\对数据访问层第一种实现(Acc+SQL)的重构        \{
 48\            OleDbConnection connection = new OleDbConnection(GetConnectionString());
 49\            OleDbCommand command = new OleDbCommand(SQLCommand, connection);
 50\
 51\            for (int i = 0; i  parameters.Length; i++)
 52\对数据访问层第一种实现(Acc+SQL)的重构            \{
 53\                command.Parameters.Add(parameters[i]);
 54\            }

 55\
 56\            connection.Open();
 57\            command.ExecuteNonQuery();
 58\            connection.Close();
 59\        }

 60\
 61\对数据访问层第一种实现(Acc+SQL)的重构        /**//// 
 62\        /// 执行SQL语句并返回包含查询结果的DataReader
 63\        /// 
 64\        /// 所执行的SQL命令
 65\        /// 参数集合
 66\        /// 

 67\        public static OleDbDataReader ExecuteSQLDataReader(string SQLCommand, OleDbParameter[] parameters)
 68\对数据访问层第一种实现(Acc+SQL)的重构        \{
 69\            OleDbConnection connection = new OleDbConnection(GetConnectionString());
 70\            OleDbCommand command = new OleDbCommand(SQLCommand, connection);
 71\
 72\            for (int i = 0; i  parameters.Length; i++)
 73\对数据访问层第一种实现(Acc+SQL)的重构            \{
 74\                command.Parameters.Add(parameters[i]);
 75\            }

 76\
 77\            connection.Open();
 78\            OleDbDataReader dataReader = command.ExecuteReader();
 79\            //connection.Close();
 80\
 81\            return dataReader;
 82\        }

 83\
 84\对数据访问层第一种实现(Acc+SQL)的重构        /**//// 
 85\        /// 执行不需要返回数据的操作
 86\        /// 
 87\        /// SQL命令
 88\        /// 参数
 89\        /// 是否成功

 90\        public static bool OperateNonData(string SQLCommand, OleDbParameter[] parameters)
 91\对数据访问层第一种实现(Acc+SQL)的重构        \{
 92\            try
 93\对数据访问层第一种实现(Acc+SQL)的重构            \{
 94\                ExecuteSQLNonQuery(SQLCommand, parameters);
 95\                return true;
 96\            }

 97\            catch
 98\对数据访问层第一种实现(Acc+SQL)的重构            \{
 99\                return false;
100\            }

101\        }

102\
103\对数据访问层第一种实现(Acc+SQL)的重构        /**//// 
104\        /// 执行返回单个实体类的操作
105\        /// 
106\        /// 实体类类型
107\        /// SQL命令
108\        /// 参数
109\        /// DataReader到实体类的转换策略
110\        /// 实体类

111\        public static T OperateEntityT>(string SQLCommand, OleDbParameter[] parameters, IDataReaderToEntityStrategyT> strategy)
112\对数据访问层第一种实现(Acc+SQL)的重构        \{
113\            OleDbDataReader dataReader = ExecuteSQLDataReader(SQLCommand, parameters);
114\            try
115\对数据访问层第一种实现(Acc+SQL)的重构            \{
116\                if (!dataReader.HasRows)
117\对数据访问层第一种实现(Acc+SQL)的重构                \{
118\                    throw new Exception();
119\                }

120\
121\                dataReader.Read();
122\                return strategy.DataReaderToEntity(dataReader);
123\            }

124\            catch
125\对数据访问层第一种实现(Acc+SQL)的重构            \{
126\                return default(T);
127\            }

128\            finally
129\对数据访问层第一种实现(Acc+SQL)的重构            \{
130\                dataReader.Close();
131\            }

132\        }

133\
134\对数据访问层第一种实现(Acc+SQL)的重构        /**//// 
135\        /// 执行返回实体类集合的操作
136\        /// 
137\        /// 实体类类型
138\        /// SQL命令
139\        /// 参数
140\        /// DataReader到实体类的转换策略
141\        /// 实体类

142\        public static IListT> OperateEntityCollectionT>(string SQLCommand, OleDbParameter[] parameters, IDataReaderToEntityStrategyT> strategy)
143\对数据访问层第一种实现(Acc+SQL)的重构        \{
144\            OleDbDataReader dataReader = AccessDALHelper.ExecuteSQLDataReader(SQLCommand, null);
145\            try
146\对数据访问层第一种实现(Acc+SQL)的重构            \{
147\                if (!dataReader.HasRows)
148\对数据访问层第一种实现(Acc+SQL)的重构                \{
149\   &
Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn