欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JAVA 链式查询

程序员文章站 2022-03-24 20:12:15
...

在开发APP的时候,发现了一个这样的小问题

像朋友圈那样的下滑刷新朋友圈,或者微博那样的下滑刷新微博

我们最开始设计的API是直接前端传递当前页数及每页条目数的传统分页

 

后来在实际开发过程中,发现此种分页有个天然的弊病,这也是所有实时更新的列表分页的弊病

就是你在点第一页的时候,恩确实没问题

但是你点第二页的时候,恰好列表被更新了N条数据,但是你传递给后端的页数及条目数并没有变

 

这导致什么后果呢,可能前端显示的是你刚查询的第一页数据的数据,看起来重复了

但是其实是因为数据更新了,刚查的第一页数据被挤到第二页了

 

JAVA 链式查询
            
    
    博客分类: mysqlJAVA  我曹!!

 

这对用户体验简直是毁灭性打击!

 

所以重新设计了API,这个API有两个参数,第一个是朋友圈某条的id,第二条是查询的条目数

每次查询接口自动返回最末尾的朋友圈id,那么此API一定不会返回错误数据了

 

废话不多说了,上代码,博主用的JPA,测试数据量为11万

 

 


JAVA 链式查询
            
    
    博客分类: mysqlJAVA  
 其中是按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 链式查询
            
    
    博客分类: mysqlJAVA  
  • 大小: 11.4 KB