在开发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
相关推荐
以下是一个简单的Java链式队列实现: ```java public class Node { int data; Node next; public Node(int data) { this.data = data; this.next = null; } } public class Queue { private Node front; ...
Java链式编程设计是一种在Java中实现优雅且简洁代码风格的技术,它允许方法调用返回对象自身,使得可以在单行代码中连续调用多个方法。这种方式通常被称为“Fluent Interface”或“Builder Pattern”。在上述描述中...
这样的设计允许开发者通过链式调用来构造复杂的查询,提高代码的可读性。 另外,`readme.txt`文件通常是项目说明或使用指南,它会包含如何使用这些工具类的详细步骤,例如如何配置数据库连接信息,如何调用类库中的...
使用示例:。SendMailParam param = SendMailParam.Builder .protocol("smtp") ... .port("25") .isAuth("true") .isEnabledDebugMod("true") ... .account(ACCOUNT) ... .sentDate(new Date()) .subject("使用JavaMail...
该项目是一款基于Java语言的链式操作POI库设计源码,涵盖72个文件,包括47个Java源文件、10个xlsx文件、5个xls文件、4个md文件等。它提供了一整套高效便捷的Excel导入导出解决方案,支持复杂表头、单元格样式、图片...
JAVA语言实现数据的链式结构 分享下挣挣人气
在Java中,队列的实现主要有三种:顺序队列、链式队列和循环队列。下面我们将详细探讨这三种队列的实现方式。 1. **顺序队列**: 顺序队列通常是基于数组实现的。在Java中,我们可以使用ArrayList或LinkedList来...
链式存储结构线性表的java实现,全代码注释,通俗易懂
在Java中,链式操作(方法链)是一种编程技巧,它允许你在单个语句中连续调用同一个对象的多个方法,使得代码更加简洁、可读性更强。这种方法在许多库和框架中被广泛使用,比如jQuery,它极大地提升了JavaScript中的...
在Java中,我们可以使用单链表来实现链式栈。下面将详细介绍链式栈的原理、实现以及相关操作。 **链式栈的基本概念** 栈是一种特殊的线性数据结构,遵循“后进先出”(Last In First Out, LIFO)原则。链式栈是用...
Java 8的Stream API提供了链式操作,方便对集合进行高效且富有表现力的聚合操作。 通过这份"JAVA快速查询手册 学习语法好助手",你可以快速查找和理解这些关键知识点,提升Java编程技能。无论你是初学者还是资深...
由于提供的文本信息是关于一篇有关Java实现链式结构的数据结构文章的一部分,因此下面将从文章的标题、描述、标签以及提供的部分内容中提炼出相关的知识点。 知识点: 1. Java的动态内存机制: Java采用动态内存...
这可以通过`Comparator`的嵌套使用来实现,或者在Java 8及以上版本中,可以利用`Comparator.comparing()`方法链式调用来实现: ```java list.sort(Comparator.comparing(Person::getAge).thenComparing(Person::...
Java实体类实现链式操作实例解析 在Java中,实体类是指封装数据和行为的类,通常用来描述业务实体。链式操作是指在实体类中实现 setter 方法返回当前对象的实例,以便在一次操作中链式调用多个 setter 方法,简化...
在C++或Java中,可以定义一个结构体或类来表示这个节点: ```cpp struct Node { char data; // 存储字符 Node* next; // 指向下一个节点的指针 }; ``` 二、串的链接 在链式存储中,串的链接过程就是创建节点并...
可以构建出一个支持链式开发的map 可以通过现有的map转换成链式开发的map 可以通过一个实体对象变成支持链式开发的map
Java 中提供了多种实现队列的方法,包括顺序队列、链式队列和循环队列等。下面我们将详细介绍每种队列的实现方法和特点。 一、顺序队列 顺序队列是指使用数组来实现队列的数据结构。它的特点是元素在数组中的位置...
在Java中,二叉树可以链式存储,即每个节点包含指向其左右子节点的引用,或者数组存储,即将所有节点存储在一个一维数组中,通过索引关系来表示父子关系。这个项目实现了这两种方式,提供了更多的灵活性。 二叉树有...
QueryBuilder的设计理念是将SQL语句的构建过程模块化,通过链式调用来构建查询结构。这使得代码更加清晰,易于阅读和调试。例如,你可以创建一个选择特定字段、从指定表中选择数据、应用WHERE条件、排序和分页的查询...
本项目为Java面向对象的SQL拼接与链式调用设计源码,包含62个文件,主要由58个Java源文件构成,辅以XML、Markdown、Git忽略和LICENSE等文件。该设计旨在降低SQL拼接错误,通过链式SQL和Lambda表达式实现高效、安全的...