馬上要畢業了,心裡很迷茫,感覺真的時間飛逝,軟體真的博大精深,特别.net平台在microsoft下變化之迅猛,個人總是趕不上技術的日新月異。哎,希望自己能早日走上設計之路。
閑來無事便根據自己大學四年項目實踐經驗,想實作一些常用子產品的抽象和內建。考慮了一下覺得先該從分頁查詢入手,便簡單的設計了下,現目前版本實作了單表的基本分頁查詢。我知道部落格園了已經有很多前輩做了這個,本人設計能力和前輩們比那就欠缺多了,有那裡不足的望指出,大家共同進步。
主要采用工廠模式建立實作了pagesqlbase的對象,然後可以利用對象的getsql()方法傳回查詢sql語句。我的目的是生成sql語句并非直接從資料庫取得資料,因為我認為如果這樣将會增加耦合度增加,不易于移植通用,也不與分頁控件結合,于是為了降低耦合度,我認為分頁控件的職責是ui的顯示而并非分頁算法等的處理,更非資料的讀取。
1.vs類圖為:
2其中pagesqlbase抽象類為:
代碼
1 namespace wolf.pager
2 {
3 public abstract class pagesqlbase
4 {
5 //查詢資訊
6 public searchinfo searchinfo
7 {
8 get;
9 set;
10 }
11 //page資訊
12 public pageinfo pageinfo
13 {
14 get;
15 set;
16 }
17 public abstract string getsql();
18 }
19 }
20
3 我在類庫實作了多種分頁算法,網上到處都有算法的描述,在這裡我就不講解了。隻展示一下針對sqlserver低版本(2000)的分頁算法選擇類,因他的算法用top并且不同的算法針對不同的主鍵和排序形式,為了效率的優化故應該選擇不同的算法。它采用的擴充卡的方式實作的。
1 using system;
2 using system.collections.generic;
3 using system.linq;
4 using system.text;
5
6 namespace wolf.pager
7 {
8 public class sqlserverlowerlevelpagesql:pagesqlbase
9 {
10 public override string getsql()
11 {
12 if (pageinfo == null || searchinfo == null)
13 {
14 throw new argumentnullexception("page資訊和search資訊不能為空!");
15 }
16 return pagesqlchoise().getsql();
17 }
18
19 protected virtual pagesqlbase pagesqlchoise()
20 {
21 if (searchinfo.uniquefieldcollection != null)
22 {
23 if (searchinfo.uniquefieldcollection.count == 1)
24 {
25 if (searchinfo.orderexpress != null)
26 {
27 if (searchinfo.orderexpress.count == 1 && searchinfo.orderexpress[0].filed.tolower()
28 .equals(searchinfo.uniquefieldcollection[0].name.tolower()))
29 {//單鍵唯一排序字段
30 return initpagesql(new topmaxpagesql());
31 }
32 else// 單鍵多排序
33 {
34 return initpagesql(new topmutilporderpagesql());
35 }
36 }
37 else//單鍵無排序(預設鍵值排序)
38 {
39 return initpagesql(new topmaxpagesql());
40 }
41 }
42 else//聯合(多)鍵
43 {
44 return initpagesql(new topmutilpkeypagesql());
45 }
46 }
47 else if (searchinfo.orderexpress != null && searchinfo.orderexpress.count > 0)
48 //無鍵(聯合建作為排序字段)//設計時把聯合建作為了排序字段
49 {
50 return initpagesql(new topmutilpkeypagesql());
51 }
52 else
53 {
54 throw new argumentnullexception("page資訊和search資訊不能為空!");
55 }
56
57 }
58
59 private pagesqlbase initpagesql(pagesqlbase psb)
60 {
61 psb.searchinfo = searchinfo;
62 psb.pageinfo = pageinfo;
63 return psb;
64 }
65 }
66 }
67
68
69
4: 工廠類的實作方式代碼如下:
1 using system;
2 using system.collections;
3 using system.reflection;
4
5 namespace wolf.pager
6 {
7 public class pagefactory
8 {
9 private static readonly pagefactory pagefactory = new pagefactory();
10 private hashtable ht;
11 private pagefactory()
12 {
13 ht = new hashtable();
14 }
15 public static pagefactory instance
16 {
17 get
18 {
19 return pagefactory;
20 }
21 }
22
23 /// <summary>
24 /// 根據配置節建立分頁算法:資料庫類型的配置優秀權大于算法dll的配置;
25 /// </summary>
26 /// <returns></returns>
27 public pagesqlbase create()
28 {
29 try
30 {
31 try
32 {
33 //先檢查config中是否配置了資料庫類型,優先級高些
34 string databasetype = system.configuration.configurationmanager.appsettings["databasetype"].tostring();
35 databasetype dbtype = (databasetype)enum.parse(typeof(databasetype), databasetype, true) ;
36 return create(dbtype);
37 }
38 catch (exception)
39 {
40 }
41 //檢查config中是否配置了算法程式資訊
42 string dll = system.configuration.configurationmanager.appsettings["assembly"].tostring();
43 string name = system.configuration.configurationmanager.appsettings["namespace"] == null ? system.configuration.configurationmanager.appsettings["assembly"].tostring()
44 : dll;
45 string type = system.configuration.configurationmanager.appsettings["type"].tostring();
46 if (string.isnullorempty(dll) || string.isnullorempty(type))
47 {
48 throw new invalidoperationexception("沒有配置pagesql節");
49 }
50 return create(dll, name, type);
51 }
52 catch (nullreferenceexception)
53 {
54
55 throw new invalidoperationexception("不存在相應配置pagesql節");
56 }
57
58
59 }
60
61 public pagesqlbase create(string dll, string type)
62 {
63 return create(dll, dll, type);
64 }
65
66 public pagesqlbase create(string dll, string name, string type)
67 {
68 //緩存,減少程式集的加載
69 string key = (dll + "$" + name + "." + type).tolower();
70 if (ht.containskey(key) && ht[key] != null)
71 {
72 type ty = ht[key].gettype();
73 object obj = ty.assembly.createinstance(ty.fullname, true);
74 return obj as pagesqlbase;
75 }
76 assembly asm = assembly.load(dll);
77 type t = asm.gettype(name + "." + type, true, true);
78 if (t.isabstract || t.isinterface || !typeof(pagesqlbase).isassignablefrom(t))
79 {
80 throw new argumentexception("目前參數不合法");
81 }
82 pagesqlbase pagesql = asm.createinstance(name + "." + type) as pagesqlbase;
83 ht.add(key, pagesql);
84 return pagesql;
85 }
86
87 public pagesqlbase create(databasetype database)
88 {
89 switch (database)
90 {
91 case databasetype.db2:
92 return db2arithmetic();
93 case databasetype.mysql:
94 return mysqlarithmetic();
95 case databasetype.oracel:
96 return oracelarithmetic();
97 case databasetype.sqlserverhightlevel:
98 return sqlserverhightlevelarithmetic();
99 case databasetype.sqlserverlowerlevel:
100 return sqlserverlowerlevelarithmetic();
101 default:
102 return defaultarithmetic();
103 }
104 }
105
106 protected virtual pagesqlbase db2arithmetic()
107 {
108 return new db2pagesql();
109 }
110
111 protected virtual pagesqlbase mysqlarithmetic()
112 {
113 return new mysqllimitpagesql();
114 }
115
116 protected virtual pagesqlbase oracelarithmetic()
117 {
118 return new oraclepagesql();
119 }
120
121 protected virtual pagesqlbase sqlserverhightlevelarithmetic()
122 {
123 return new mssql2005row_numberpagesql();
124 }
125
126 protected virtual pagesqlbase sqlserverlowerlevelarithmetic()
127 {
128 return new sqlserverlowerlevelpagesql();
129 }
130
131 protected virtual pagesqlbase defaultarithmetic()
132 {
133 return new topmutilporderpagesql();
134 }
135 }
136 }
137
138
我的測試配置configu為:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appsettings>
<add key="databasetype" value="sqlserverlowerlevel"/>
<!--<add key="assembly" value="consoletest"/>
<add key="namespace" value="consoletest"/>
<add key="type" value="program"/>-->
</appsettings>
</configuration>
測試結果性能比較高效,具體大家把代碼下載下傳看。
本版本隻是一個初步的實踐摸索版本,離使用還應該差一些,我會有時間在改進,主要應該還要加入:
1:多表查詢的分頁方式。
2:groupby分組統計方式的分頁查詢。
3:添加是記憶體資料統計的類庫。
4:緩存機制的加入(初步打算用os的頁面置換算法lru(最近最少使用),加入逾時減少緩存帶來的資料不一緻性)。
分頁控件的設計暫時沒考慮太多,我認為web控件應該可以支援url、poatback、ajax三種方式,具體實作可以用簡單工廠。winform的當然就一種方式了。資料庫處理應該有程式員了事件代碼中挂載。ui和bl層必須與資料層相隔離。
希望能先多開發些常用子產品,減少以後的代碼量,加快開發速度。我的目标是能開發一個小型管理系統的通用開發和配置平台。