說明:
不知道還有沒有其他的比較好的方式,這個是目前我能想到比較好的實現。如有錯誤還請指正。如果有更好的分表分頁實現方式還請告知。
必要條件:
查詢時必須選擇開始時間和結束時間。這樣可以知道要查詢哪些表,如果不選就是查詢所有表,就失去了分表的意義。(題外話:如果業務場景允許建議嘗試使用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語句都是基礎的查詢,這里就不粘了。