在开发APP的时候,发现了一个这样的小问题
像朋友圈那样的下滑刷新朋友圈,或者微博那样的下滑刷新微博
我们最开始设计的API是直接前端传递当前页数及每页条目数的传统分页
后来在实际开发过程中,发现此种分页有个天然的弊病,这也是所有实时更新的列表分页的弊病
就是你在点第一页的时候,恩确实没问题
但是你点第二页的时候,恰好列表被更新了N条数据,但是你传递给后端的页数及条目数并没有变
这导致什么后果呢,可能前端显示的是你刚查询的第一页数据的数据,看起来重复了
但是其实是因为数据更新了,刚查的第一页数据被挤到第二页了
我曹!!
这对用户体验简直是毁灭性打击!
所以重新设计了API,这个API有两个参数,第一个是朋友圈某条的id,第二条是查询的条目数
每次查询接口自动返回最末尾的朋友圈id,那么此API一定不会返回错误数据了
废话不多说了,上代码,博主用的JPA,测试数据量为11万
其中是按weight权重为1排序,默认排序是是按权重及创建时间
@Override public BlogController.Linn<Blog> gets(Integer pageSize, String lastId) { Long firstNum = 1l; //当不是第一个的时候lastID需要算自己 if("-1".equals(lastId)){ //获取当前排序条件及查询条件下的第一条信息 lastId = blogRepository.getFirstId(); firstNum = 0L; } //获取后续 Long follow=blogRepository.getFollow(lastId); List<Blog> dbs = blogRepository.linnSelect(follow+firstNum,pageSize,lastId); BlogController.Linn l = new BlogController.Linn(); l.setData(dbs); l.setLastId(dbs.get(dbs.size()-1).getId()); return l; }
具体sql语句
@Query(nativeQuery = true,value = "SELECT id from jf_blog ORDER BY weight ASC, create_date DESC limit 0,1") String getFirstId(); /** * 获取在特定排序条件下 * 低于或高于这个排序条件下的个数 * @param id * @return */ @Query(nativeQuery = true,value = "SELECT COUNT(*) FROM jf_blog WHERE 1=1\n" + "AND weight < (SELECT weight FROM jf_blog WHERE id = ?1)") Long getPrior(String id); /** * 在特定排序下 * 对特定排序条件相同 * 则比较系统默认排序 * @param id * @return */ @Query(nativeQuery = true,value = "select count(*) from jf_blog \n" + "where 1=1\n" + "and weight = (SELECT weight FROM jf_blog WHERE id = ?1) \n" + "and create_date > (select create_date from jf_blog where id = ?1);") Long getFollow(String id); /** * 瀑布查询 * @param pageSize * @return */ @Query(nativeQuery = true,value = "Select * from jf_blog " + "where 1=1\n" + "AND weight >= (SELECT weight FROM jf_blog WHERE id = ?3)"+ "ORDER BY weight ASC, create_date DESC limit ?1,?2") List<Blog> linnSelect(Long follow,Integer pageSize,String id);
这里只是简单的一种weight排序下(创建时间为默认排序,且理论上认为其为原子性的,要求高的可自建序列,或使用sql自带的序列)
最后在10万条数目下,查询20条数据大概在0.3秒左右,而原生分页查询速度在6秒左右。
对于更大数量的,确实需要分页的问题,请参考下面的博客
http://www.cnblogs.com/geningchao/p/6649907.html
相关推荐
使用示例:。SendMailParam param = SendMailParam.Builder .protocol("smtp") ... .port("25") .isAuth("true") .isEnabledDebugMod("true") ... .account(ACCOUNT) ... .sentDate(new Date()) .subject("使用JavaMail...
JAVA语言实现数据的链式结构 分享下挣挣人气
链式存储结构线性表的java实现,全代码注释,通俗易懂
一般情况下,对一个类的实例和操作,是采用这种方法进行的: Channel channel = new Channel(); channel.queueDeclare(QUEUE_NAME, true, false, false, null); int prefetchCount = 1; ...
java队列实现(顺序队列、链式队列、循环队列)
NULL 博文链接:https://128kj.iteye.com/blog/1618731
主要介绍了JAVA中实现链式操作的例子,模仿jQuery的方法链实现,需要的朋友可以参考下
本文实例为大家分享了js设计模式之链式调用的具体代码,供大家参考,具体内容如下 写过jquery的可能都知道,jquery里面可以很方便的使用以下代码: // 不使用链式调用 const element = $(ele); element.addClass('...
下面小编就为大家分享一篇java队列实现方法(顺序队列,链式队列,循环队列),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
利用java写了两个案例是关于二叉树和平衡树的分别为数组的和链式的。 功能: 1.三种历遍方式的输出。 2.平衡树的重构。 3.节点的添加以及删除。 4.平均查找长度的计算。
主要介绍了Java实体类实现链式操作实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
NULL 博文链接:https://128kj.iteye.com/blog/1617944
JDK1.8Java代码开发规范 1.利于代码工整、维护 2.避免系统、内存等问题发生 正规公司非常需要规范程序猿的代码标准
该资源为本人翻遍大部分帖子、博客、资源等一系列资料自我整合了一套技术分享的Demo,以Java为载体,使用浅显易懂的代码,阐述Lambda表达式 与java的结合使用,以及Stream流的基本方法与collect()、reduce()等...
主要介绍了Java及Android中常用链式调用写法,结合实例形式分析了java编程中的链式调用概念、简单使用方法及相关操作技巧,需要的朋友可以参考下
使用链式编程写法实现Java中byte数组的拼接。例如byte[] bytes = ByteUtils.get().add(0x41).add(07).add(11).add("15288930000").add(0x45).toArray();更灵活用法请参考Mybytes
java 向量的实现 栈实现 队列实现 链表的实现 二叉树的实现 求二叉树的深度 按层次遍历二叉树 求二叉树的宽度 各类排序算法java实现
通过本课程的学习,学员可以掌握以下技术点:线性结构与顺序表、单向链表、循环链表、栈的基本概念、链式堆栈、中缀表达式、队列、链式队列、串、MyString、Brute-Force算法、MySet类实现、矩阵类、递归算法、哈夫曼...
包装了Map对象,使其更加容易操作
本篇文章主要介绍用JAVA 实现二叉树,并提供实例.对二叉树数据结构很好的学习实践,有需要的朋友可以参考下