分页查询算法实践
马上要毕业了,心里很迷茫,感觉真的时间飞逝,软件真的博大精深,特别.NET平台在Microsoft下变化之迅猛,个人总是赶不上技术的日新月异。哎,希望自己能早日走上设计之路。
闲来无事便根据自己大学四年项目实践经验,想实现一些常用模块的抽象和集成。考虑了一下觉得先该从分页查询入手,便简单的设计了下,现目前版本实现了单表的基本分页查询。我知道博客园了已经有很多前辈做了这个,本人设计能力和前辈们比那就欠缺多了,有那里不足的望指出,大家共同进步。
下载代码:WolfPager下载
主要采用工厂模式创建实现了PageSqlBase的对象,然后可以利用对象的GetSql()方法返回查询Sql语句。我的目的是生成sql语句并非直接从数据库取得数据,因为我认为如果这样将会增加耦合度增加,不易于移植通用,也不与分页控件结合,于是为了降低耦合度,我认为分页控件的职责是UI的显示而并非分页算法等的处理,更非数据的读取。
1.VS类图为:
2其中PageSqlBase抽象类为:
![复制代码](http://common.cnblogs.com/images/copycode.gif)
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
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
![复制代码](http://common.cnblogs.com/images/copycode.gif)
3 我在类库实现了多种分页算法,网上到处都有算法的描述,在这里我就不讲解了。只展示一下针对SqlServer低版本(2000)的分页算法选择类,因他的算法用Top并且不同的算法针对不同的主键和排序形式,为了效率的优化故应该选择不同的算法。它采用的适配器的方式实现的。
![复制代码](http://common.cnblogs.com/images/copycode.gif)
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
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
![复制代码](http://common.cnblogs.com/images/copycode.gif)
4: 工厂类的实现方式代码如下:
![复制代码](http://common.cnblogs.com/images/copycode.gif)
![](http://images.cnblogs.com/OutliningIndicators/ExpandedBlockStart.gif)
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
![复制代码](http://common.cnblogs.com/images/copycode.gif)
我的测试配置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层必须与数据层相隔离。
希望能先多开发些常用模块,减少以后的代码量,加快开发速度。我的目标是能开发一个小型管理系统的通用开发和配置平台。
【SQL开发实战技巧】系列(二十二):数仓报表场景☞ 从分析函数效率一定快吗聊一聊结果集分页和隔行抽样实现方式 怎样对SQL查询结果集分页比较好、平时你用分析函数优化传统查询,所以你会不会认为分析函数一定比传统查询效率高?一个实验告诉你答案、我想对数据进行隔行抽样应该怎么实现?【SQL开发实战技巧】这一系列博主当作复习旧知识来进行写作,毕竟SQL开发在数据分析场景非常重要且基础,面试也会经常问SQL开发和调优经验,相信当我写完这一系列文章,也能再有所收获,未来面对SQL面试也能游刃有余~。分析查询的一个小建议,可能大家平时为了方便,用row_number做分页的比较多,但是在有些场景,这个效率真的挺低。
好好编程-物流项目15【基础数据-分页查询和添加】 项目中我们往往要用到很多数据量不大且不会经常变动的数据,比如部门信息,付款方式,性别等信息,如果这些信息我们都单独用一张表来维护,显示不是很明智,所以我们可以将这一类数据统一存放在一张表中。通过数据结构来维护
相关文章
- Java实现 蓝桥杯VIP 算法训练 邮票
- Java实现 蓝桥杯 算法训练 排序
- DNS的概念,用途,DNS查询的实现算法
- 数据挖掘案例:基于 ReliefF和K-means算法的应用
- 【python cookbook】【数据结构与算法】9.在两个字典中寻找相同点
- DL之模型调参:深度学习算法模型优化参数之对LSTM算法进行超参数调优
- 第十四届蓝桥杯集训——练习解题阶段(无序阶段)-ALGO-1 算法训练 区间k大数查询
- 【自适应滤波】基于FxLMS的样条自适应滤波算法分析(Matlab代码实现)
- 基于蜣螂算法改进的DELM分类-附代码
- 1906. 查询差绝对值的最小值-动态规划算法
- 白话经典算法系列之五 归并排序的实现
- ES设置查询的相似度算法
- Lucene4.2源码解析之fdt和fdx文件的读写(续)——fdx文件存储一个个的Block,每个Block管理着一批Chunk,通过docID读取到document需要完成Segment、Block、Chunk、document四级查询,引入了LZ4算法对fdt的chunk docs进行了实时压缩/解压