博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
分页查询算法实践
阅读量:6181 次
发布时间:2019-06-21

本文共 6679 字,大约阅读时间需要 22 分钟。

 

马上要毕业了,心里很迷茫,感觉真的时间飞逝,软件真的博大精深,特别.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 

 

我在类库实现了多种分页算法,网上到处都有算法的描述,在这里我就不讲解了。只展示一下针对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.0encoding="utf-8" ?>

<configuration>

 <appSettings>

    <add key="DataBaseTypevalue="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层必须与数据层相隔离。

 

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

作者: 
出处: 
本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该文章也同时发布在我的独立博客中-、和。http://www.cnblogs.com/whitewolf/archive/2010/03/12/WolfPager.html

你可能感兴趣的文章
IF 比较操作表达
查看>>
16、产品经理指南 - 软件项目角色指南系列文章
查看>>
ZRANGEBYLEX key min max [LIMIT offset count]
查看>>
普通用户免输密码切换root
查看>>
MySQL to Hbase 数据的抽取
查看>>
【AIX】AIX 开机自动挂载NFS共享
查看>>
对PS1的理解
查看>>
IO学习总结一
查看>>
CentOS 6.4下PXE+Kickstart无人值守安装操作系统
查看>>
glusterfs——volume管理
查看>>
[译] 认证 vs 授权
查看>>
Linux的磁盘格式化,磁盘挂载,手动增加swap空间
查看>>
更改SharePoint的服务器名称
查看>>
Java泛型应用浅析
查看>>
CCNA课堂练习:nat的介绍及利用nat来实现地址转换
查看>>
权威详解 | 阿里新一代实时计算引擎 Blink,每秒支持数十亿次计算
查看>>
企业域名更换操作系列5:上传DomainList.XML文件
查看>>
oracle表结构及表数据的复制
查看>>
数据库应用软件开发前3个步骤之实例讲解
查看>>
【ZooKeeper Notes 13】ZooKeeper Watcher的事件通知类型
查看>>