范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

全栈角度看分页处理

  分页是 web application 开发最常见的功能。在使用不同的框架和工具过程中,发现初始行/页的定义不同,特意整理记录。从这个技术点去看不同层的实现。以及不同语言实现的对比。
  文章会从正常的web 结构分层的角度去梳理不同层的处理,分为数据库分页、服务端分页、前端分页三部分。
  一、数据库分页
  这里用mysql 举例整理。我们常用的数据库例如 Oracle/ SQL Server 等,对于分页语法的支持大同小异。不做具体一一举例。
  先从数据库层梳理,也是从最根源去分析分页的最终目的,前端和后端的一起逻辑和适配,都是为了拼接合适的 SQL 语句。
  1.MySQL LIMIT
  语法:[LIMIT {[ offset ,]  row_count }]
  LIMIT row_count is equivalent to LIMIT 0, row_count.
  The offset of the initial row is 0 (not 1)
  参考:MySQL :: MySQL 5.7 Reference Manual :: 13.2.9 SELECT Statement
  二、服务端/后端分页
  后端分页,简单讲,就是数据库的分页。对于mysql 来讲,就是上述 offset row_count 的计算过程。
  这里选用了常用的框架组件来对比各自实现的细节。
  pagehelper 是Java Orm 框架mybatis 常用的开源分页插件
  spring-data-jdbc 是Java 框架常用的数据层组件 1.pagehelper/**  * 计算起止行号  offset  * @see com.github.pagehelper.Page#calculateStartAndEndRow  */ private void calculateStartAndEndRow() {     // pageNum 页码,从1开始。pageNum < 1 , 忽略计算。     this.startRow = this.pageNum > 0 ? (this.pageNum - 1) * this.pageSize : 0;     this.endRow = this.startRow + this.pageSize * (this.pageNum > 0 ? 1 : 0); }/**  * 计算总页数 pages/ pageCount。  * 在赋值数据总条数的同时,也计算了总页数。  * 可以与 Math.ceil 实现对比看。  */ public void setTotal(long total) {     if (pageSize > 0) {         pages = (int) (total / pageSize + ((total % pageSize == 0) ? 0 : 1));     } else {         pages = 0;     } }
  SQL 拼接实现:com.github.pagehelper.dialect.helper.MySqlDialect 2.spring-data-jdbc
  关键类:
  org.springframework.data.domain.Pageable
  org.springframework.data.web.PageableDefault /**  * offset 计算,不同于pagehelper, page 页码从0 开始。default is 0  * @see org.springframework.data.domain.AbstractPageRequest#getOffset  */ public long getOffset() {     return (long)this.page * (long)this.size; }   /*  * 总页数的计算使用 Math.ceil 实现。  * @see org.springframework.data.domain.Page#getTotalPages()  */ @Override public int getTotalPages() {     return getSize() == 0 ? 1 : (int) Math.ceil((double) total / (double) getSize()); }/**  * offset 计算,不同于pagehelper, page 页码从0 开始。  * @see org.springframework.data.jdbc.core.convert.SqlGenerator#applyPagination  */ private SelectBuilder.SelectOrdered applyPagination(Pageable pageable, SelectBuilder.SelectOrdered select) {     // 在spring-data-relation, Limit 抽象为 SelectLimitOffset      SelectBuilder.SelectLimitOffset limitable = (SelectBuilder.SelectLimitOffset) select;     // To read the first 20 rows from start use limitOffset(20, 0). to read the next 20 use limitOffset(20, 20).     SelectBuilder.SelectLimitOffset limitResult = limitable.limitOffset(pageable.getPageSize(), pageable.getOffset());       return (SelectBuilder.SelectOrdered) limitResult; }
  spring-data-commons 提供 mvc 层的分页参数处理器 /**  * Annotation to set defaults when injecting a {@link org.springframework.data.domain.Pageable} into a controller method.   *  * @see org.springframework.data.web.PageableDefault  */ @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.PARAMETER) public @interface PageableDefault {       /**      * The default-size the injected {@link org.springframework.data.domain.Pageable} should get if no corresponding      * parameter defined in request (default is 10).      */     int size() default 10;       /**      * The default-pagenumber the injected {@link org.springframework.data.domain.Pageable} should get if no corresponding      * parameter defined in request (default is 0).      */     int page() default 0; }
  MVC 参数处理器:org.springframework.data.web.PageableHandlerMethodArgumentResolver
  三、前端分页
  前端展示层,分别从服务端渲染方案以及纯前端脚本方案去看分页最终的页面呈现逻辑。
  这里选取的分别是Java 常用的模板引擎 thymeleaf 以及热门的前端框架 element-ui。
  从用法以及组件源码角度,去理清终端处理分页的常见方式。 1.thymeleaf - 模板引擎
  Thymeleaf is a modern server-side Java template engine for both web and standalone environments.  2.element-ui 前端框架// from node_moduleselement-uipackagespaginationsrcpagination.js // page-count 总页数,total 和 page-count 设置任意一个就可以达到显示页码的功能; computed: {   internalPageCount() {     if (typeof this.total === "number") {       // 页数计算使用 Math.ceil       return Math.max(1, Math.ceil(this.total / this.internalPageSize));     } else if (typeof this.pageCount === "number") {       return Math.max(1, this.pageCount);     }     return null;   } },   /**  * 起始页计算。page 页码从1 开始。  */ getValidCurrentPage(value) {   value = parseInt(value, 10);   // 从源码的实现可以看到,一个稳定强大的开源框架,在容错、边界处理的严谨和思考。   const havePageCount = typeof this.internalPageCount === "number";     let resetValue;   if (!havePageCount) {     if (isNaN(value) || value < 1) resetValue = 1;   } else {     // 强制赋值起始值 1     if (value < 1) {       resetValue = 1;     } else if (value > this.internalPageCount) {       // 数据越界,强制拉回到PageCount       resetValue = this.internalPageCount;     }   }     if (resetValue === undefined && isNaN(value)) {     resetValue = 1;   } else if (resetValue === 0) {     resetValue = 1;   }     return resetValue === undefined ? value : resetValue; }
  四、总结
  技术永远是关联的,思路永远是相似的,方案永远是相通的。单独的去分析某个技术或者原理,总是有边界和困惑存在。纵向拉伸,横向对比才能对技术方案有深刻的理解。在实战应用中,能灵活自如。
  分页实现的方案最终是由数据库决定的,对于众多的数据库,通过SQL 语法的规范去框定,以及我们常用的各种组件或者插件去适配。
  纵向对比,我们可以看到不同技术层的职责和通用适配的实现过程,对于我们日常的业务通用开发以及不同业务的兼容有很大的借鉴意义。
  横向对比,例如前端展示层的实现思路,其实差别非常大。如果使用 thymeleaf,结构简单清晰,但交互响应上都会通过服务器。如果选用element-ui,分页只依赖展示层,和服务端彻底解构。在技术选型中可以根据各自的优缺点进行适度的抉择。
  作者:杨攀
  来源:微信公众号:京东云开发者
  出处:https://mp.weixin.qq.com/s/u3K7LjRNQOVQdfGxzjkvwQ

有人预测2022年地球有可能被小行星碰撞,若是真的,人类会灭绝吗?即兴一首七言作答八大飞天绕骄阳,四十亿年不偏航,土木携卫布内巡,冥海天王外围防。昂首北斗定标向,九霄银河一路畅,妄传荒谬今杞忧,苟延残喘信雌黄。注自上世纪末至今几十年间,关于世界未芯片已发展到2nm,摩尔定律会失效吗?芯片技术无法突破了吗?2nm,2纳米,相当于2乘10负9次方米。2nm芯片是指光刻机每次曝光时留下介质层的间距,不是指整个芯片大小只有2nm。例如如果用7nm的光刻机,要实现2nm的芯片,需要最少曝光4刺激战场抗锯齿到底开不开,有什么利弊?相信刚刚开始玩刺激战场的玩家们,都会存在着一个疑惑,那就是抗锯齿到底要不要打开?抗锯齿究竟对游戏有没有影响?抗锯齿有存在的必要吗?首先,我们需要了解的是,抗锯齿的作用。在游戏中,抗国足真的无可救药吗?中国男足不是无药可救,不过已经是病入膏肓了,要想妙手回春必须要进行大刀阔斧的改革,中国足球必须要经历大折腾了,不是一年花2300万欧元请一个里皮就能解彻底解决国足的问题,他也是治标红米note4x酷派cool1魅蓝note6荣耀8青春版哪一台值得入手?个人推荐魅蓝note6!魅蓝Note6采用中端神U骁龙625移动平台,它是首款采用14nmFinFET制程的骁龙600系列处理器,功耗较上一代产品降低35,带来优质用户体验的同时,饭店的菜肉随便洗洗,甚至不洗,为什么很少有人吃了拉肚子?我在烹饪学校学过三年厨师,毕业以后很多饭店都从事过厨师工作,后来自己也开了接近10年饭店,因此对于餐饮行业我也算是一个业内人士。饭店的经营现在受到的监管很多,尤其是卫生防疫部门,对数学公式是因为被发现才存在,还是本身就存在?数学公式是人类对世界本来的固有的客观规律的主观反映和符号表达。自然规律早已存在,只是在被人认识了之后,才用公式表达了出来。数学公式自然是原本不存在的,虽然他的原理虽是科学的,合理的苏伟和韩德君两位冠军中锋,是否会同时退役?苏伟和韩德君两位冠军中锋,是否会同时退役?这道不一定,每支球队情况各不相同,无论广东或辽宁就说有年轻中锋补上来,但年轻中锋必定比赛经验欠缺,也还要一些老将进行传帮带,这又不是按什么怎样提高英语成绩?我认为提高英语成绩是对英语学习的兴趣,很多家长认为英语学习只需要背单词,背课文就行,但是实际情况是孩子每天在背单词,过几天忘记了,然后就是被家长逼着背课文,结果是孩子很累也很烦,对请问上合肥七中大概需要怎样的成绩?合肥七中是省级示范高中,教学水平和质量都比较靠前,分数线排名会在168之后,目前合肥市七中新小区已经启用。都是处于住宿阶段。下面给大家看下这几年合肥七中的录取分数线这块我们调取了从普通人若中彩票大奖,把奖金全部存银行会被调查吗?数额比较巨大,一定会被调查的但是只要能证明资金来源正当,就没问题。许多银行对存取款的金额有着明确规定,比如说一位储户的月流水不足1万元,却在某一个月忽然上涨到5万元,银行就会对该储
年卡突然取消!上海迪士尼发公告没得不限次数进场了!3月17日消息,上海迪士尼乐园通过官方小程序发布了年卡暂停办理通告,于今日上午8点开始暂停所有形式的年卡办理,但年卡续费不受影响。据悉,上海迪士尼共有无限钻石卡星光钻石卡和梦幻水晶魔神劫火燃战九霄逍遥情缘全新资料片上线,一起迎战蚩尤吧!魔神劫火,燃战九霄!最近,魔神蚩尤得到了新的力量,觉醒了全新的形态,这也意味着将有更大的挑战等待着少侠们去面对。同时,逍遥情缘以开放一个新服务器势如破竹,并准备了大量的福利活动等待拳皇(KingofFighters)红白机游戏拳皇(KingofFighters,缩写为KOF)是由日本SNK公司开发的一款格斗游戏系列,于1994年首次发布。该系列以固定画面的2D格斗为主要特点,包含了大量的角色和战斗场景。逍遥情缘手游打架累了就来欢乐棋局对弈一把吧游玩逍遥情缘手游,战斗多了总会有疲倦的时候,这时候我们不妨换换口味,来一场不依靠角色和宠物实力的欢乐棋局吧。这是最近新上线的一个休闲玩法,可以跟其他玩家下棋对弈,棋局的胜负主要依赖巴基斯坦女孩和你握手是啥意思?导游先别高兴,你可能回不去了自从我们国家开始改革开放的国策之后,国家的经济发展有了快速的发展,而经济的发展又促进了百姓生活水平的提高,现在,人们不仅生活好了,收入也更多了。(此处已添加小程序,请到今日头条客户黑帮大佬杜月笙?在他面前,也只能称小弟上期我们讲到了杜月笙,这位上个世纪上海滩的黑道传奇,叱咤风云好不威风。但是今天要讲述的这个人,地位之显赫,连杜月笙都要尊称大哥,他就是上海滩虹口三杰之首,黄金荣,今天就让我们一起,同比下降173月112日国内乘用车销量出炉!进入2023年,由于各种原因的影响,国内汽车产业的消费趋势并没有意料之中的增长,反而跌幅较大。自1月1日起,全国乘用车市场累计零售309。4万辆,同比去年下降19。不过,新能源汽车杭氧股份,世界级隐形冠军!杭氧股份,我是2018年开始关注的,这公司很有意思,从2010上市以后的十年期间,股价一直处于低位震荡,没有上涨,直到2020年,股价开始进入了上升期。但事实上呢,杭氧股份的业绩一孔明珠啦啦物语啦啦在幼儿园上学,喜欢唱歌跳舞,喜欢游泳滑雪,是个汉语和英语轮流切换的5岁小女孩。(一)OK小谷啦啦家里有一只小谷声控智能音响,摆在屋角的小茶几上,是个淡灰色圆圆的东西,爸爸经常叫以存量换增量,苏州相城探索存量空间盘活新路径日前,在苏州市相城经开区高端智能制造产业园区内,谈浜路徐家观路泗荡泾路三条内部道路顺利完工通车,产业园内的毛细血管进一步畅通。这里曾经是散乱污整治的重点区域,如今已成为经开区三城建WTT大满贯17日赛程!王楚钦内战林高远,女单力争包揽四强北京时间3月16日,2023年WTT大满贯赛新加坡站正赛第6个比赛日结束。该比赛日进行了男单下半区的18决赛,女单上半区的18决赛,混双决赛,以及男女双打的14决赛。自此,男女单打