天天看点

分页查询算法实践

马上要毕业了,心里很迷茫,感觉真的时间飞逝,软件真的博大精深,特别.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层必须与数据层相隔离。

希望能先多开发些常用模块,减少以后的代码量,加快开发速度。我的目标是能开发一个小型管理系统的通用开发和配置平台。