按天分表后分页查询java实现

 

说明:

  不知道还有没有其他的比较好的方式,这个是目前我能想到比较好的实现。如有错误还请指正。如果有更好的分表分页实现方式还请告知。

必要条件:

  查询时必须选择开始时间和结束时间。这样可以知道要查询哪些表,如果不选就是查询所有表,就失去了分表的意义。(题外话:如果业务场景允许建议尝试使用ES,很香。)

第一步,查询各个分表符合条件的条数: 

     //填充查询条件。
        MapBuilder<Object, Object> paramBuild = MapUtil.builder()
                .put("startDate", startDate.getTime())
                .put("endDate", endDate.getTime());

        Map<String, Long> countMap = new TreeMap<>();
        int i = 0;
        DateTime tmpStartDate;
        do {
            //从开始时间递增到结束时间
            tmpStartDate = DateUtil.offsetDay(startDate, i++);
            String yyyyMMdd = tmpStartDate.toString("yyyyMMdd");
            //检查该日期表是否存在
            if (checkTableExists(yyyyMMdd)) {
                Map<Object, Object> map = paramBuild
                        .put("yyyyMMdd", yyyyMMdd)
                        .build();
                //根据该日期表有多少符合条件的条数
                Long count = getBaseMapper().getCount(map);
                if (count != null && count > 0) {
                    //如果有条数放入有序map中,方便之后的分页计算。
                    countMap.put(yyyyMMdd, count);
                }
            }
            //判断是否递增到结束时间,这里开始时间初始必须小于或等于结束时间。
        } while (!DateUtil.isSameDay(tmpStartDate, endDate));

第二步,分页计算并获取数据:

     //前端传过来的页码
        int pageNo = vosCdrLogVO.getPageNo();
        //前端传过来的分页条数
        int pageSize = vosCdrLogVO.getPageSize();

        //计算所有分表符合条件的总条数
        long total = countMap.values().stream().mapToLong(Long::longValue).sum();
        //计算总页数
        long totalPageNum = (total + pageSize - 1) / pageSize;
        if (pageNo > totalPageNum) {
            return pageInfo;
        }
        
        //根据前端传的页码和每页条数,计算limit开始位置。
        int limitStart = (pageNo - 1) * pageSize;
        long sum = 0;
        List<Cdr> list = new ArrayList<>();
        //下面的计算自己看吧,我已经忘了当时怎么想的,不想再看了。
        for (Map.Entry<String, Long> entry : countMap.entrySet()) {
            sum += entry.getValue();
            if (sum > limitStart) {
                Map<Object, Object> map = paramBuild
                        .put("limitStart", entry.getValue() - (sum - limitStart))
                        .put("pageSize", pageSize)
                        .put("yyyyMMdd", entry.getKey())
                        .build();
                List<Cdr> tmpList = getBaseMapper().selectByParam(map);
                list.addAll(tmpList);
                if (list.size() < pageSize) {
                    //该分表数据不够一页,查询下个分表。
                    pageSize = pageSize - tmpList.size();
                    limitStart = limitStart + tmpList.size();
                } else {
                    break;
                }
            }
        }

        pageInfo.setTotal(total);
        pageInfo.setPages((int) totalPageNum);
        pageInfo.setPageNum(pageNo);
        pageInfo.setPageSize(vosCdrLogVO.getPageSize());
        pageInfo.setList(list);
        return pageInfo;

结语

以上代码 有些变量没粘进来,不过都是无关紧要的。

用到的一些工具类 都是 hutool里的,可自行引入。pageInfo 是pagehelper分页插件里的对象。查询的sql语句都是基础的查询,这里就不粘了。

上一篇:LINQ to Entities 不支持指定的类型成员“Date”。


下一篇:Dynamics CRM - 關於 QueryExpression 的分頁查詢