马上要毕业了,心里很迷茫,感觉真的时间飞逝,软件真的博大精深,特别.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层必须与数据层相隔离。
希望能先多开发些常用模块,减少以后的代码量,加快开发速度。我的目标是能开发一个小型管理系统的通用开发和配置平台。