Maison >base de données >tutoriel mysql >对数据访问层第一种实现(Acc+SQL)的重构

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

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBoriginal
2016-06-07 15:11:121290parcourir

昨天的文章基于.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\   &
Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn