• 分页查询算法实践


     

    马上要毕业了,心里很迷茫,感觉真的时间飞逝,软件真的博大精深,特别.NET平台在Microsoft下变化之迅猛,个人总是赶不上技术的日新月异。哎,希望自己能早日走上设计之路。

    闲来无事便根据自己大学四年项目实践经验,想实现一些常用模块的抽象和集成。考虑了一下觉得先该从分页查询入手,便简单的设计了下,现目前版本实现了单表的基本分页查询。我知道博客园了已经有很多前辈做了这个,本人设计能力和前辈们比那就欠缺多了,有那里不足的望指出,大家共同进步。

    下载代码:WolfPager下载

    主要采用工厂模式创建实现了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, truetrue);
     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层必须与数据层相隔离。

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


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

  • 相关阅读:
    把一件简单的事情做好你就不简单了
    一个经验尚浅的码农五年软件开发的一点自我总结,对工作五年的反思~
    我就是一名房地产经纪人!不是中介,谁能明白我们呢?
    我与父辈的酒局
    郎意难坚,侬情自热(文/王路)
    红灯须硬闯,马路要横穿(文/王路)
    孩子,你慢慢来
    职场六年后的一点点感言
    有幸见到一朵花的绽放
    当你遇到她
  • 原文地址:https://www.cnblogs.com/whitewolf/p/WolfPager.html
Copyright © 2020-2023  润新知