zoukankan      html  css  js  c++  java
  • 关于PDF.NET开发框架对Mysql Sqlite PostgreSQL数据库分页支持的个人看法

     关于PDF.NET开发框架的名字由来 

             在设计www.pwmis.com站点的时候,考虑到架构的兼容性和将来升级的可能性,最重要的是没有足够的时间去为网站添加和维护很多复杂的程序,所以在借鉴前人成功经验的基础上,设计了一套全新的快速数据处理框架 PWMIS Data Develop Framework,简称PDF。 

      本套框架的思想是借鉴Java平台的Hibernate 和 iBatis 而来,兼有ORM和SQL-MAP的特性,同时还参考了后来.NET的LINQ(本框架成型于2006年,当时还未听说过LINQ)使用风格,设计了OQL查询表达式。本框架的设计思想是通用的,完全可以移植到Java 平台,现在只提供了.NET平台的实现,暂且将本框架命名为 PDF.NET(当前测试版 4.6.4.0528

     

      关于我与此框架的关系

      偶尔得知(看MOON.Orm对pdf cyq ClownFish等框架进行性能对比)这套框架不错,便想看看到底如何。从百度搜索,搜到官网,并下载阅读之。因为之前反编译了Moon.ORM,并把修改后的部分核心代码交给了原作者,就算促进中国软件的进步吧,一直想搞一套很厉害的底层,所以拜读之,写此文,并无任何攻击的恶意,因为我不喜欢那些天天喷的家伙,只为探讨技术并获取pdf svn账号获取最新代码而已。

    首先我们先看查询细节,以MySql为例

     

    -----------------------------------------------------------------------------------------

    使用Offset方式

    -----------------------------------------------------------------------------------------

    说明了什么呢?即offset是把数据记录从0开始索引(0条,1条,2条.......)

    先把PDF.NET原代码附上:

    private static string MakePageSQLStringByMySQL_PgSQL(string strSQLInfo, string strWhere, int PageSize, int PageNumber, int AllCount, string offsetString)
            {
                strSQLInfo = strSQLInfo.Trim();
                //去除末尾的分号
                if (strSQLInfo.EndsWith(";"))
                    strSQLInfo = strSQLInfo.TrimEnd(';');
                if (strWhere != null && strWhere != "")
                {
                    strWhere = strWhere.Trim().ToUpper();
                    if (strWhere.StartsWith("WHERE "))
                        throw new Exception("附加查询条件不能带 where 谓词");
                    if (strWhere.IndexOf(" ORDER BY ") > 0)
                        throw new Exception("附加查询条件不能带 ORDER BY 谓词");
                    strSQLInfo = "SELECT * FROM (" + strSQLInfo + ") temptable0 WHERE " + strWhere;
                }
                if (AllCount == 0)
                {
                    //生成统计语句 
                    return "select count(*) from (" + strSQLInfo + ") ";
                }
    
                if (PageNumber == 1)
                    return strSQLInfo + " LIMIT " + PageSize;
                int offset = PageSize * PageNumber;
                if (offsetString == ",")//MySQL,感谢网友[左眼]发现此Bug
                    return strSQLInfo + " LIMIT " + offset + offsetString + PageSize;
                else //PostgreSQL
                    return strSQLInfo + " LIMIT " + PageSize + offsetString + offset;
            }

    1.用pdf框架开发Mysql Sqlite PostgreSQL数据库的朋友在进行分页时要小心了,(PageNumber为2,即会查询出第3页的数据,依此类推......)。

    2.用+号来进行字符串拼接,本人还是觉得StringBuilder要好,因为传入的strSQLInfo可能大量sql语句。效率.......

    进过修改后的代码为:

     1 private static string MakePageSQLStringByMySQL_PgSQL1(string strSQLInfo, string strWhere, int PageSize, int PageNumber, int AllCount, string offsetString)
     2         {
     3             strSQLInfo = strSQLInfo.Trim();
     4             //去除末尾的分号
     5             if (strSQLInfo.EndsWith(";"))
     6                 strSQLInfo = strSQLInfo.TrimEnd(';');
     7 
     8             StringBuilder sb = new StringBuilder();
     9             if (string.IsNullOrEmpty(strWhere))
    10             {
    11                 sb.Append(strSQLInfo);
    12             }
    13             else
    14             {
    15                 strWhere = strWhere.TrimStart();
    16                 if (strWhere.StartsWith("WHERE ", StringComparison.OrdinalIgnoreCase))
    17                     throw new Exception("附加查询条件不能带 where 谓词");
    18                 if (strWhere.LastIndexOf(" ORDER BY ", StringComparison.OrdinalIgnoreCase) > 0)
    19                     throw new Exception("附加查询条件不能带 ORDER BY 谓词");
    20 
    21                 sb.Append("SELECT * FROM (")
    22                   .Append(strSQLInfo)
    23                   .Append(") temptable0 WHERE ")
    24                   .Append(strWhere);
    25 
    26                 //sb.AppendFormat("SELECT * FROM ({0}) temptable0 WHERE {1}", strSQLInfo, strWhere);
    27             }
    28 
    29             if (AllCount == 0)
    30             {
    31                 //生成统计语句 
    32                 sb.Insert(0, "select count(*) from (").Append(") ");
    33             }
    34             else
    35             {
    36                 int offset = PageSize * (PageNumber - 1);//应该是 PageSize * (PageNumber -1)  而不是  PageSize * PageNumber
    37                 sb.AppendFormat(" LIMIT {0} OFFSET {1}", PageSize, offset);
    38             }
    39             return sb.ToString();
    40         }

    最终测试代码: 

     1  //这么做是因为是查询的语句在实际环境下几乎每次不同,而字符串类的实现方式用了享元模式(同样的字符串内容,在内存中只有一个实例),所以我们用不同的 String实例
     2             string strInfo = @"SELECT SelectField{0},SelectField{1},SelectField2,SelectField3,SelectField4,SelectField5,SelectField6,SelectField7 FROM 
     3                                  FROM TABLE{0}
     4                              ORDER BY OrderField1 DESC,OrderField2 ASC";
     5             string where = " 1=1 and (name='张三' and age=20 and sex=0) or(game='过家家' and num={0} and num1={1}) ";
     6             List<string> infoList = new List<string>();
     7             List<string> whereList = new List<string>();
     8             //准备测试数据
     9             for (int i = 0; i < 500000; i++)
    10             {
    11                 infoList.Add(string.Format(strInfo, i, i + 1));
    12                 whereList.Add(string.Format(where, i, i + 1));
    13             }
    14             //string page
    15             Stopwatch sw = new Stopwatch();
    16             sw.Start();
    17             for (int i = 1; i < 500000; i++)
    18             {
    19                 MakePageSQLStringByMySQL_PgSQL(infoList[i], whereList[i], 20, i, 10000, string.Empty);
    20             }
    21             sw.Stop();
    22             double stringPageTime = sw.Elapsed.TotalMilliseconds / 1000;
    23             //string count
    24             sw.Restart();
    25             for (int i = 1; i < 500000; i++)
    26             {
    27                 MakePageSQLStringByMySQL_PgSQL(infoList[i], whereList[i], 20, i, 0, string.Empty);
    28             }
    29             sw.Stop();
    30             double stringCountTime = sw.Elapsed.TotalMilliseconds / 1000;
    31 
    32             //StringBuilder page
    33             sw.Restart();
    34             for (int i = 1; i < 500000; i++)
    35             {
    36                 MakePageSQLStringByMySQL_PgSQL1(infoList[i], whereList[i], 20, i, 10000, string.Empty);
    37             }
    38             sw.Stop();
    39             double stringBuilderTime = sw.Elapsed.TotalMilliseconds / 1000;
    40             //StringBuilder count
    41             sw.Restart();
    42             for (int i = 1; i < 500000; i++)
    43             {
    44                 MakePageSQLStringByMySQL_PgSQL1(infoList[i], whereList[i], 20, i, 0, string.Empty);
    45             }
    46             sw.Stop();
    47             double stringBuilderCountTime = sw.Elapsed.TotalMilliseconds / 1000;
    48 
    49             MessageBox.Show("构造分页语句: " + stringPageTime.ToString() + " 秒    构造count: " + stringCountTime.ToString() + ""
    51                           + "构造分页语句1:" + stringBuilderTime.ToString() + " 秒    构造count1:" + stringBuilderCountTime.ToString() + "");

    结果附上,大家可以自己测下:

  • 相关阅读:
    代码收藏
    sql语句收藏
    网站收藏
    Api代码收集
    [网络收集]html 一个属性,多个数据
    [转] C#自定义的字符串操作增强类
    WebBrowser记录
    [转载]用C#的GDI+技术生成复杂型彩色验证码
    js addEventListener attachEvent用法
    正则表达式 获取常见所有标点符号
  • 原文地址:https://www.cnblogs.com/dujuncn/p/3293280.html
Copyright © 2011-2022 走看看