采用什么样的数据访问形式是软件编码很重要的一个环节,良好的数据访问形式不仅能够提搞代码的执行效率,协作能力,更重要的是对未来程序维护,功能扩展起到至关重要的作用。当然良好的设计模式可以为我们提供很多的选择,但面对实际问题,公司规模小考虑成本,资金投入少,软件逻辑不算复杂,功能较少,部分客户需求只需要单个功能模块,类似小型管理系统,门户网站,crm等,这也为众多IT人事提供了兼职的好机会。借鉴类似程序,cpy下部分代码,小修小改下数据库字段新的软件就大功告成。这种现状在弊端同时也很多程序没有通过完整的测试,部分存在漏洞,维护性不高,导致客户日常投诉反工现象时有发生,弄不好还会引起不必要的麻烦,为此组件一个高效便捷的快速开发框架,集成我们日常生活中的经验是十分有必要的。
这里我就结合几个项目中用到的简单的数据访问层简单和大家共同的学习探讨。
1、常用数据访问我们一般采用的都有:微软自带DBHelper
2、Enterprises Library微软企业库(Microsoft.Practices.EnterpriseLibrary.Common,Microsoft.Practices.EnterpriseLibrary.Data,Microsoft.Practices.ObjectBuilder)
3、这里我和大家共同探讨结合微软DBHelper的自定义的加强版SqlDataProvider.cs
数据库访问抽象类DataProvider.cs
1 using System;2 using System.Collections.Generic;3 using System.Linq;4 using System.Text;5 using System.Data.SqlClient;6 using System.Configuration;7 using System.Data;8 using System.Reflection;9 using System.Data.OleDb;
10 namespace DAL
11 {
12 ///<summary>
13 /// 数据库访问抽象类
14 ///</summary>
15 public abstract class DataProvider
16 {
17 private static DataProvider _instance = null;
18 public static DataProvider Instance
19 {
20 get
21 {
22 if (_instance == null)
23 {
24 String strConnectionString = ConfigurationManager.ConnectionStrings["ConnnectionString"].ConnectionString;
25
26 String strConnectionType = ConfigurationManager.ConnectionStrings["ConnectionType"].ConnectionString;
27 if (strConnectionType.ToLower() == "sqlclient")
28 {
29 strConnectionType = "DAL.SqlDataProvider, DAL";
30 }
31
32 Type t = Type.GetType(strConnectionType);
33 Type[] paramTypes = new Type[1];
34 paramTypes[0] = typeof(String);
35
36 Object[] paramArray = new Object[1];
37 paramArray[0] = strConnectionString;
38
39 _instance = (DataProvider)((ConstructorInfo)t.GetConstructor(paramTypes)).Invoke(paramArray);
40 }
41 return _instance;
42 }
43 }
44
45 #region 抽象属性和方法
46
47 #region 数据库链接串
48 public abstract String ConnectionString { get; }
49 #endregion
50
51 #region 执行SQL语句
52 public abstract Object GetScalar(String selectSql);
53 public abstract DataSet GetDataset(String selectSql);
54 public virtual DataSet GetDatasetTrans(SqlTransaction trans, String selectSql) { return null; }
55 public virtual DataSet GetDatasetTrans(OleDbTransaction trans, String selectSql) { return null; }
56 public virtual DataSet GetDataset(String selectSql, SqlParameter[] para) { return null; }
57 public virtual DataSet GetDataset(String selectSql, OleDbParameter[] para) { return null; }
58 public virtual DataSet GetDatasetTrans(SqlTransaction trans, String selectSql, SqlParameter[] para) { return null; }
59 public virtual DataSet GetDatasetTrans(OleDbTransaction trans, String selectSql, OleDbParameter[] para) { return null; }
60 public abstract void Execute(String noneQuery);
61 public virtual void Execute(String noneQuery, SqlParameter[] para) { }
62 public virtual void Execute(String noneQuery, OleDbParameter[] para) { }
63 public abstract IDataReader GetReader(String selectSql);
64 public virtual IDataReader GetReaderTrans(SqlTransaction trans, String selectSql) { return null; }
65 public virtual IDataReader GetReaderTrans(OleDbTransaction trans, String selectSql) { return null; }
66 public virtual IDataReader GetReader(String selectSql, SqlParameter[] para) { return null; }
67 public virtual IDataReader GetReader(String selectSql, OleDbParameter[] para) { return null; }
68 public virtual IDataReader GetReaderTrans(SqlTransaction trans, String selectSql, SqlParameter[] para) { return null; }
69 public virtual IDataReader GetReaderTrans(OleDbTransaction trans, String selectSql, OleDbParameter[] para) { return null; }
70 #endregion
71
72 #region 执行存储过程
73 public abstract void ExecuteSp(String spName);
74 public virtual void ExecuteSp(SqlTransaction trans, String spName) { }
75 public virtual void ExecuteSp(OleDbTransaction trans, String spName) { }
76 public virtual void ExecuteSp(String spName, SqlParameter[] para) { }
77 public virtual void ExecuteSp(String spName, OleDbParameter[] para) { }
78 public virtual void ExecuteSp(SqlTransaction trans, String spName, SqlParameter[] para) { }
79 public virtual void ExecuteSp(OleDbTransaction trans, String spName, OleDbParameter[] para) { }
80 public abstract IDataReader GetReaderBySp(String spName);
81 public virtual IDataReader GetReaderBySp(String spName, SqlParameter[] para) { return null; }
82 public virtual IDataReader GetReaderBySp(String spName, OleDbParameter[] para) { return null; }
83 public abstract Object GetScalarBySp(String spName);
84 public virtual Object GetScalarBySp(String spName, SqlParameter[] para) { return null; }
85 public virtual Object GetScalarBySp(String spName, OleDbParameter[] para) { return null; }
86 public abstract DataSet GetDatasetBySp(String spName);
87 public virtual DataSet GetDatasetBySp(String spName, SqlParameter[] para) { return null; }
88 public virtual DataSet GetDatasetBySp(String spName, OleDbParameter[] para) { return null; }
89 #endregion
90
91 #endregion
92 }
93 }
继承类SqlDataProvider:
1 using System;2 using System.Collections.Generic;3 using System.Linq;4 using System.Text;5 using System.Data;6 using System.Data.SqlClient;7 namespace DAL8 {9 public class SqlDataProvider : DataProvider10 {11 private String _connectionString = String.Empty;12 13 public SqlDataProvider(String connString)14 {15 _connectionString = connString;16 }17 18 #region 实现抽象方法19 20 #region 数据库链接串21 public override String ConnectionString22 {23 get24 {25 return _connectionString;26 }27 }28 29 #endregion30 31 #region 执行SQL语句32 33 ///<summary>34 /// 执行查询获取单值35 ///</summary>36 ///<param name="selectSql">查询语句</param>37 ///<returns>返回Object</returns>38 public override Object GetScalar(String selectSql)39 {40 return SqlHelper.ExecuteScalar(_connectionString,41 CommandType.Text, selectSql);42 }43 44 ///<summary>45 /// 根据查询语句获取数据集46 ///</summary>47 ///<param name="selectSql">查询语句</param>48 ///<returns>返回数据集</returns>49 public override DataSet GetDataset(String selectSql)50 {51 if (selectSql == null) throw new ArgumentNullException("selectSql");52 53 DataSet ds = new DataSet();54 SqlHelper.FillDataset(_connectionString, CommandType.Text, selectSql, ds, null);55 return ds;56 }57 58 ///<summary>59 /// 根据查询语句获取数据集60 ///</summary>61 ///<param name="trans">事务</param>62 ///<param name="selectSql">查询语句</param>63 ///<returns>返回数据集</returns>64 public override DataSet GetDatasetTrans(SqlTransaction trans, String selectSql)65 {66 if (selectSql == null) throw new ArgumentNullException("selectSql");67 68 DataSet ds = new DataSet();69 SqlHelper.FillDataset(trans, CommandType.Text, selectSql, ds, null);70 return ds;71 }72 73 ///<summary>74 /// 根据带参数的查询语句获取数据集75 ///</summary>76 ///<param name="selectSql">查询语句</param>77 ///<param name="para">参数列表</param>78 ///<returns>返回数据集</returns>79 public override DataSet GetDataset(String selectSql, SqlParameter[] para)80 {81 if (selectSql == null) throw new ArgumentNullException("selectSql");82 if (para == null) throw new ArgumentNullException("para");83 84 DataSet ds = new DataSet();85 SqlHelper.FillDataset(_connectionString, CommandType.Text, selectSql, ds, null, para);86 return ds;87 }88 89 ///<summary>90 /// 根据带参数的查询语句获取数据集91 ///</summary>92 ///<param name="trans">事务</param>93 ///<param name="selectSql">查询语句</param>94 ///<param name="para">参数列表</param>95 ///<returns>返回数据集</returns>96 public override DataSet GetDatasetTrans(SqlTransaction trans, String selectSql, SqlParameter[] para)97 {98 if (selectSql == null) throw new ArgumentNullException("selectSql");99 if (para == null) throw new ArgumentNullException("para");
100
101 DataSet ds = new DataSet();
102 SqlHelper.FillDataset(trans, CommandType.Text, selectSql, ds, null, para);
103 return ds;
104 }
105
106 ///<summary>
107 /// 在某个数据库连接对象上执行查询语句获取数据集
108 ///</summary>
109 ///<param name="cn">数据库连接对象</param>
110 ///<param name="selectSql">查询语句</param>
111 ///<returns>返回数据集</returns>
112 public static DataSet GetDataset(SqlConnection conn, String selectSql)
113 {
114 if (conn == null) throw new ArgumentNullException("conn");
115 if (selectSql == null) throw new ArgumentNullException("selectSql");
116
117 DataSet ds = new DataSet();
118 SqlHelper.FillDataset(conn, CommandType.Text, selectSql, ds, null);
119 return ds;
120 }
121
122 ///<summary>
123 /// 执行非查询语句
124 ///</summary>
125 ///<param name="noneQuery">非查询sql语句</param>
126 public override void Execute(String noneQuery)
127 {
128 if (noneQuery == null) throw new ArgumentNullException("noneQuery");
129
130 SqlHelper.ExecuteNonQuery(_connectionString, CommandType.Text, noneQuery);
131 }
132
133 ///<summary>
134 /// 执行非查询语句
135 ///</summary>
136 ///<param name="noneQuery">非查询sql语句</param>
137 ///<param name="para">参数列表</param>
138 public override void Execute(String noneQuery, SqlParameter[] para)
139 {
140 if (noneQuery == null) throw new ArgumentNullException("noneQuery");
141 if (para == null) throw new ArgumentNullException("para");
142
143 SqlHelper.ExecuteNonQuery(_connectionString, CommandType.Text, noneQuery, para);
144 }
145
146 ///<summary>
147 /// 执行查询语句获取Reader对象
148 ///</summary>
149 ///<param name="selectSql">查询语句</param>
150 ///<returns>返回DataReader</returns>
151 public override IDataReader GetReader(String selectSql)
152 {
153 if (selectSql == null) throw new ArgumentNullException("selectSql");
154
155 return SqlHelper.ExecuteReader(_connectionString, CommandType.Text, selectSql);
156 }
157
158 ///<summary>
159 /// 执行查询语句获取Reader对象
160 ///</summary>
161 ///<param name="trans">事务</param>
162 ///<param name="selectSql">查询语句</param>
163 ///<returns>返回DataReader</returns>
164 public override IDataReader GetReaderTrans(SqlTransaction trans, String selectSql)
165 {
166 if (selectSql == null) throw new ArgumentNullException("selectSql");
167
168 return SqlHelper.ExecuteReader(trans, CommandType.Text, selectSql);
169 }
170
171 ///<summary>
172 /// 执行查询语句获取Reader对象
173 ///</summary>
174 ///<param name="selectSql">查询语句</param>
175 ///<param name="para">参数列表</param>
176 ///<returns>返回DataReader</returns>
177 public override IDataReader GetReader(String selectSql, SqlParameter[] para)
178 {
179 if (selectSql == null) throw new ArgumentNullException("selectSql");
180 if (para == null) throw new ArgumentNullException("para");
181
182 return SqlHelper.ExecuteReader(_connectionString, CommandType.Text, selectSql, para);
183 }
184
185 ///<summary>
186 /// 执行查询语句获取Reader对象
187 ///</summary>
188 ///<param name="trans">事务</param>
189 ///<param name="selectSql">查询语句</param>
190 ///<param name="para">参数列表</param>
191 ///<returns>返回DataReader</returns>
192 public override IDataReader GetReaderTrans(SqlTransaction trans, String selectSql, SqlParameter[] para)
193 {
194 if (selectSql == null) throw new ArgumentNullException("selectSql");
195 if (para == null) throw new ArgumentNullException("para");
196
197 return SqlHelper.ExecuteReader(trans, CommandType.Text, selectSql, para);
198 }
199
200 #endregion
201
202 #region 执行存储过程
203 ///<summary>
204 /// 执行非查询存储过程
205 ///</summary>
206 ///<param name="spName">存储过程名称</param>
207 public override void ExecuteSp(String spName)
208 {
209 if (spName == null) throw new ArgumentNullException("spName");
210
211 SqlHelper.ExecuteNonQuery(_connectionString, CommandType.StoredProcedure, spName);
212 }
213
214 ///<summary>
215 /// 执行非查询存储过程
216 ///</summary>
217 ///<param name="trans">事务对象</param>
218 ///<param name="spName">存储过程名称</param>
219 public override void ExecuteSp(SqlTransaction trans, String spName)
220 {
221 if (trans == null) throw new ArgumentNullException("trans");
222 if (spName == null) throw new ArgumentNullException("spName");
223
224 SqlHelper.ExecuteNonQuery(trans, CommandType.StoredProcedure, spName);
225 }
226
227 ///<summary>
228 /// 执行非查询存储过程
229 ///</summary>
230 ///<param name="spName">存储过程名称</param>
231 ///<param name="para">参数列表</param>
232 public override void ExecuteSp(String spName, SqlParameter[] para)
233 {
234 if (spName == null) throw new ArgumentNullException("spName");
235 if (para == null) throw new ArgumentNullException("para");
236
237 SqlHelper.ExecuteNonQuery(_connectionString, CommandType.StoredProcedure, spName, para);
238 }
239
240 /// 执行非查询存储过程
241 ///</summary>
242 ///<param name="trans">事务对象</param>
243 ///<param name="spName">存储过程名称</param>
244 ///<param name="para">参数列表</param>
245 public override void ExecuteSp(SqlTransaction trans, String spName, SqlParameter[] para)
246 {
247 if (trans == null) throw new ArgumentNullException("trans");
248 if (spName == null) throw new ArgumentNullException("spName");
249 if (para == null) throw new ArgumentNullException("para");
250
251 SqlHelper.ExecuteNonQuery(trans, CommandType.StoredProcedure,
252 spName, para);
253 }
254
255 ///<summary>
256 /// 执行查询存储过程获取Reader对象
257 ///</summary>
258 ///<param name="spName">存储过程名称</param>
259 ///<returns>返回DataReader</returns>
260 public override IDataReader GetReaderBySp(String spName)
261 {
262 if (spName == null) throw new ArgumentNullException("spName");
263
264 return SqlHelper.ExecuteReader(_connectionString,
265 CommandType.StoredProcedure, spName);
266 }
267
268 ///<summary>
269 /// 执行查询存储过程获取Reader对象
270 ///</summary>
271 ///<param name="spName">存储过程名称</param>
272 ///<param name="para">参数列表</param>
273 ///<returns>返回DataReader</returns>
274 public override IDataReader GetReaderBySp(String spName, SqlParameter[] para)
275 {
276 return SqlHelper.ExecuteReader(_connectionString,
277 CommandType.StoredProcedure, spName, para);
278 }
279
280 ///<summary>
281 /// 执行查询存储过程获取单值
282 ///</summary>
283 ///<param name="spName">存储过程名称</param>
284 ///<returns>返回Object</returns>
285 public override Object GetScalarBySp(String spName)
286 {
287 return SqlHelper.ExecuteScalar(_connectionString,
288 CommandType.StoredProcedure, spName);
289 }
290
291 ///<summary>
292 /// 执行查询存储过程获取单值
293 ///</summary>
294 ///<param name="spName">存储过程名称</param>
295 ///<param name="para">参数列表</param>
296 ///<returns>返回Object</returns>
297 public override Object GetScalarBySp(String spName, SqlParameter[] para)
298 {
299 return SqlHelper.ExecuteScalar(_connectionString,
300 CommandType.StoredProcedure, spName, para);
301 }
302
303 ///<summary>
304 /// 根据存储过程获取数据集
305 ///</summary>
306 ///<param name="spName">存储过程</param>
307 ///<returns>返回数据集</returns>
308 public override DataSet GetDatasetBySp(String spName)
309 {
310 if (spName == null) throw new ArgumentNullException("spName");
311
312 DataSet ds = new DataSet();
313 SqlHelper.FillDataset(_connectionString, CommandType.StoredProcedure, spName, ds, null);
314 return ds;
315 }
316 ///<summary>
317 /// 根据带参数的存储过程获取数据集
318 ///</summary>
319 ///<param name="spName">存储过程</param>
320 ///<param name="para">参数列表</param>
321 ///<returns>返回数据集</returns>
322 public override DataSet GetDatasetBySp(String spName, SqlParameter[] para)
323 {
324 if (spName == null) throw new ArgumentNullException("spName");
325 if (para == null) throw new ArgumentNullException("para");
326
327 DataSet ds = new DataSet();
328 SqlHelper.FillDataset(_connectionString, CommandType.StoredProcedure, spName, ds, null, para);
329 return ds;
330 }
331 #endregion
332
333 #endregion
334 }
335 }
微软本身是的SqlHelper类提供高性能可扩充的数据库访问方法,代码就不啰嗦大家都懂的,通过集成和改造对数据访问的安全性,扩展性做进一步的伸展
测试 同时加载1w条数据试一试,方法执行时间,忽略浏览器加载时间
改造数据访问:
方法执行时间
企业库:
方法执行时间
普通DBHlper:
方法执行时间
同时加载10W条数据试一试:
改造后10W条数据访问时间:
企业库10W数据访问时间:
普通DBHelper,10W条数据访问时间:
当然了测试和机器配置也相关,以上数据仅供参考,不一定准确,还有很多地方不是很完善,你的项目采用的是什么数据交互模式来?有没有更好的意见和建议,期待达人们的意见和建议。