查看: 5551|回复: 0
打印 上一主题 下一主题

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

[复制链接]
跳转到指定楼层
1#
发表于 2008-7-2 19:03:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
台州网址导航
昨天的文章基于.NET平台的分层架构实战(七)——数据访问层的第一种实现:Access+SQL发布后,很多朋友对我的程序提出了意见和建议,在这里先谢谢你们!!!尤其是 金色海洋(jyk),对我的程序提出了很多建设性的意见。

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

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

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

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

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

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




下面来看一下具体代码:

首先是IDataReaderToEntityStrategy接口
IDataReaderToEntityStrategy
1using System;
2using System.Collections.Generic;
3using System.Text;
4using System.Data;
5using System.Data.OleDb;
6
7namespace NGuestBook.AccessDAL
8{
9    /**//// <summary>
10    /// 由DataReader转换成实体类的策略接口
11    /// </summary>
12    public interface IDataReaderToEntityStrategy<T>
13    {
14        /**//// <summary>
15        /// 将DataReader转换为实体类,采用泛型
16        /// </summary>
17        /// <param name="dataReader">包含数据的DataReader对象</param>
18        /// <returns>实体类</returns>
19        T DataReaderToEntity(OleDbDataReader dataReader);
20    }
21}


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

1using System;
  2using System.Collections.Generic;
  3using System.Web;
  4using System.Web.Caching;
  5using System.Configuration;
  6using System.Data;
  7using System.Data.OleDb;
  8using NGuestBook.Utility;
  9
10namespace NGuestBook.AccessDAL
11{
12    /**//// <summary>
13    /// Access数据库操作助手
14    /// </summary>
15    public sealed class AccessDALHelper
16    {
17        /**//// <summary>
18        /// 读取Access数据库的连接字符串
19        /// 首先从缓存里读取,如果不存在则到配置文件中读取,并放入缓存
20        /// </summary>
21        /// <returns>Access数据库的连接字符串</returns>
22        private static string GetConnectionString()
23        {
24            if (CacheAccess.GetFromCache("AccessConnectionString") != null)
25            {
26                return CacheAccess.GetFromCache("AccessConnectionString").ToString();
27            }
28            else
29            {
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        /**//// <summary>
42        /// 执行SQL语句并且不返回任何值
43        /// </summary>
44        /// <param name="SQLCommand">所执行的SQL命令</param>
45        /// <param name="parameters">参数集合</param>
46        public static void ExecuteSQLNonQuery(string SQLCommand, OleDbParameter[] parameters)
47        {
48            OleDbConnection connection = new OleDbConnection(GetConnectionString());
49            OleDbCommand command = new OleDbCommand(SQLCommand, connection);
50
51            for (int i = 0; i < parameters.Length; i++)
52            {
53                command.Parameters.Add(parameters);
54            }
55
56            connection.Open();
57            command.ExecuteNonQuery();
58            connection.Close();
59        }
60
61        /**//// <summary>
62        /// 执行SQL语句并返回包含查询结果的DataReader
63        /// </summary>
64        /// <param name="SQLCommand">所执行的SQL命令</param>
65        /// <param name="parameters">参数集合</param>
66        /// <returns></returns>
67        public static OleDbDataReader ExecuteSQLDataReader(string SQLCommand, OleDbParameter[] parameters)
68        {
69            OleDbConnection connection = new OleDbConnection(GetConnectionString());
70            OleDbCommand command = new OleDbCommand(SQLCommand, connection);
71
72            for (int i = 0; i < parameters.Length; i++)
73            {
74                command.Parameters.Add(parameters);
75            }
76
77            connection.Open();
78            OleDbDataReader dataReader = command.ExecuteReader();
79            //connection.Close();
80
81            return dataReader;
82        }
83
84        /**//// <summary>
85        /// 执行不需要返回数据的操作
86        /// </summary>
87        /// <param name="SQLCommand">SQL命令</param>
88        /// <param name="parameters">参数</param>
89        /// <returns>是否成功</returns>
90        public static bool OperateNonData(string SQLCommand, OleDbParameter[] parameters)
91        {
92            try
93            {
94                ExecuteSQLNonQuery(SQLCommand, parameters);
95                return true;
96            }
97            catch
98            {
99                return false;
100            }
101        }
102
103        /**//// <summary>
104        /// 执行返回单个实体类的操作
105        /// </summary>
106        /// <typeparam name="T">实体类类型</typeparam>
107        /// <param name="SQLCommand">SQL命令</param>
108        /// <param name="parameters">参数</param>
109        /// <param name="strategy">DataReader到实体类的转换策略</param>
110        /// <returns>实体类</returns>
111        public static T OperateEntity<T>(string SQLCommand, OleDbParameter[] parameters, IDataReaderToEntityStrategy<T> strategy)
112        {
113            OleDbDataReader dataReader = ExecuteSQLDataReader(SQLCommand, parameters);
114            try
115            {
116                if (!dataReader.HasRows)
117                {
118                    throw new Exception();
119                }
120
121                dataReader.Read();
122                return strategy.DataReaderToEntity(dataReader);
123            }
124            catch
125            {
126                return default(T);
127            }
128            finally
129            {
130                dataReader.Close();
131            }
132        }
133
134        /**//// <summary>
135        /// 执行返回实体类集合的操作
136        /// </summary>
137        /// <typeparam name="T">实体类类型</typeparam>
138        /// <param name="SQLCommand">SQL命令</param>
139        /// <param name="parameters">参数</param>
140        /// <param name="strategy">DataReader到实体类的转换策略</param>
141        /// <returns>实体类</returns>
142        public static IList<T> OperateEntityCollection<T>(string SQLCommand, OleDbParameter[] parameters, IDataReaderToEntityStrategy<T> strategy)
143        {
144            OleDbDataReader dataReader = AccessDALHelper.ExecuteSQLDataReader(SQLCommand, null);
145            try
146            {
147                if (!dataReader.HasRows)
148                {
149                    throw new Exception();
150                }
151
152                IList<T> entityCollection = new List<T>();
153                int i = 0;
154                while (dataReader.Read())
155                {
156                    entityCollection.Add(strategy.DataReaderToEntity(dataReader));
157                    i++;
158                }
159
160                return entityCollection;
161            }
162            catch
163            {
164                return default(IList<T>);
165            }
166            finally
167            {
168                dataReader.Close();
169            }
170        }
171    }
172}


最后以Admin为例,看一下简化后的数据访问层实现:

1using System;
  2using System.Collections.Generic;
  3using System.Text;
  4using System.Data;
  5using System.Data.OleDb;
  6using NGuestBook.IDAL;
  7using NGuestBook.Entity;
  8
  9namespace NGuestBook.AccessDAL
10{
11    public class AdminDAL : IAdminDAL
12    {
13        /**//// <summary>
14        /// 插入管理员
15        /// </summary>
16        /// <param name="admin">管理员实体类</param>
17        /// <returns>是否成功</returns>
18        public bool Insert(AdminInfo admin)
19        {
20            string SQLCommand = "insert into [TAdmin]([Name],[Password]) values(@name,@password)";
21            OleDbParameter[] parameters ={
22                new OleDbParameter("name",OleDbType.VarChar,20),
23                new OleDbParameter("password",OleDbType.VarChar,50)
24            };
25            parameters[0].Value = admin.Name;
26            parameters[1].Value = admin.Password;
27
28            return AccessDALHelper.OperateNonData(SQLCommand, parameters);
29        }
30
31        /**//// <summary>
32        /// 删除管理员
33        /// </summary>
34        /// <param name="id">欲删除的管理员的ID</param>
35        /// <returns>是否成功</returns>
36        public bool Delete(int id)
37        {
38            string SQLCommand = "delete from [TAdmin] where [ID]=@id";
39            OleDbParameter[] parameters ={
40                new OleDbParameter("id",OleDbType.Integer)
41            };
42            parameters[0].Value = id;
43
44            return AccessDALHelper.OperateNonData(SQLCommand, parameters);
45        }
46
47        /**//// <summary>
48        /// 更新管理员信息
49        /// </summary>
50        /// <param name="admin">管理员实体类</param>
51        /// <returns>是否成功</returns>
52        public bool Update(AdminInfo admin)
53        {
54            string SQLCommand = "update [TAdmin] set [Name]=@name,[Password]=@password where [ID]=@id";
55            OleDbParameter[] parameters ={
56                new OleDbParameter("id",OleDbType.Integer),
57                new OleDbParameter("name",OleDbType.VarChar,20),
58                new OleDbParameter("password",OleDbType.VarChar,50)
59            };
60            parameters[0].Value = admin.ID;
61            parameters[1].Value = admin.Name;
62            parameters[2].Value = admin.Password;
63
64            return AccessDALHelper.OperateNonData(SQLCommand, parameters);
65        }
66
67        /**//// <summary>
68        /// 按ID取得管理员信息
69        /// </summary>
70        /// <param name="id">管理员ID</param>
71        /// <returns>管理员实体类</returns>
72        public AdminInfo GetByID(int id)
73        {
74            string SQLCommand = "select * from [TAdmin] where [ID]=@id";
75            OleDbParameter[] parameters ={
76                new OleDbParameter("id",OleDbType.Integer)
77            };
78            parameters[0].Value = id;
79
80            return AccessDALHelper.OperateEntity<AdminInfo>(SQLCommand, parameters, AdminDataReaderToEntityStrategy.GetInstance());
81        }
82
83        /**//// <summary>
84        /// 按用户名及密码取得管理员信息
85        /// </summary>
86        /// <param name="name">用户名</param>
87        /// <param name="password">密码</param>
88        /// <returns>管理员实体类,不存在时返回null</returns>
89        public AdminInfo GetByNameAndPassword(string name, string password)
90        {
91            string SQLCommand = "select * from [TAdmin] where [Name]=@name and [Password]=@password";
92            OleDbParameter[] parameters ={
93                new OleDbParameter("name",OleDbType.VarChar,20),
94                new OleDbParameter("password",OleDbType.VarChar,50)
95            };
96            parameters[0].Value = name;
97            parameters[1].Value = password;
98
99            return AccessDALHelper.OperateEntity<AdminInfo>(SQLCommand, parameters, AdminDataReaderToEntityStrategy.GetInstance());
100        }
101
102        /**//// <summary>
103        /// 按管理员名取得管理员信息
104        /// </summary>
105        /// <param name="name">管理员名</param>
106        /// <returns>管理员实体类</returns>
107        public AdminInfo GetByName(string name)
108        {
109            string SQLCommand = "select * from [TAdmin] where [Name]=@name";
110            OleDbParameter[] parameters ={
111                new OleDbParameter("name",OleDbType.VarChar,20)
112            };
113            parameters[0].Value = name;
114
115            return AccessDALHelper.OperateEntity<AdminInfo>(SQLCommand, parameters, AdminDataReaderToEntityStrategy.GetInstance());
116        }
117
118        /**//// <summary>
119        /// 取得全部管理员信息
120        /// </summary>
121        /// <returns>管理员实体类集合</returns>
122        public IList<AdminInfo> GetAll()
123        {
124            string SQLCommand = "select * from [TAdmin]";
125
126            return AccessDALHelper.OperateEntityCollection<AdminInfo>(SQLCommand, null, AdminDataReaderToEntityStrategy.GetInstance());
127        }
128    }
129}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享 分享淘帖
台州维博网络(www.tzweb.com)专门运用PHP+MYSQL/ASP.NET+MSSQL技术开发网站门户平台系统等。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

网站推广
关于我们
  • 台州朗动科技(Tzweb.com)拥有多年开发网站平台系统门户手机客户端等业务的成功经验。主要从事:政企网站,系统平台,微信公众号,各类小程序,手机APP客户端,浙里办微应用,浙政钉微应用、主机域名、虚拟空间、后期维护等服务,满足不同企业公司的需求,是台州地区领先的网络技术服务商!

Hi,扫描关注我

Copyright © 2005-2026 站长论坛 All rights reserved

Powered by 站长论坛 with TZWEB Update Techonolgy Support

快速回复 返回顶部 返回列表