JAVA 链式查询

在开发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

 

猜你喜欢

转载自liaoke0123.iteye.com/blog/2381688