说明:
不知道还有没有其他的比较好的方式,这个是目前我能想到比较好的实现。如有错误还请指正。如果有更好的分表分页实现方式还请告知。
必要条件:
查询时必须选择开始时间和结束时间。这样可以知道要查询哪些表,如果不选就是查询所有表,就失去了分表的意义。(题外话:如果业务场景允许建议尝试使用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语句都是基础的查询,这里就不粘了。