设为首页 收藏本站
查看: 3466|回复: 0

[经验分享] 关于PDF.NET开发框架对Mysql Sqlite PostgreSQL数据库分页支持的个人看法

[复制链接]

尚未签到

发表于 2015-6-26 17:37:13 | 显示全部楼层 |阅读模式
  
  关于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为例
DSC0000.jpg


DSC0001.jpg DSC0002.jpg
  -----------------------------------------------------------------------------------------
  使用Offset方式
  -----------------------------------------------------------------------------------------
DSC0003.jpg
DSC0004.png
  说明了什么呢?即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 infoList = new List();
7             List whereList = new List();
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, whereList, 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, whereList, 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, whereList, 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, whereList, 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() + " 秒\n"
51                           + "构造分页语句1:" + stringBuilderTime.ToString() + " 秒    构造count1:" + stringBuilderCountTime.ToString() + " 秒");
  结果附上,大家可以自己测下:

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-80782-1-1.html 上篇帖子: SQLServer(MSSQL)、MySQL、SQLite、Access相互迁移转换工具 DB2DB v1.4 下篇帖子: 功能齐全、效率一流的免费开源数据库导入导出工具(c#开发,支持SQL server、SQLite、ACCESS三种数据库),每月借此处理数据5G以上
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表