美文网首页
java后台分页算法小记

java后台分页算法小记

作者: haiyong6 | 来源:发表于2020-11-06 20:10 被阅读0次

说到分页,可能大部分人喜欢用mybatisplus自带的插件或者其他什么人写的插件。
可能也是习惯问题,我喜欢自己写分页,有几个好处,第一不挑数据库,也不挑持久层框架,甚至jdbc都能用。第二,可以避免代码的不透明度,避免出错时难定位。

controller层加page和rows参数

page:当前页码
rows:每页显示的条数
当然名称都可以自定义

    @PostMapping(value = "/test")
    ResponseVO getData(@RequestHeader(required = true) String uid,
            @RequestHeader(name = "reqid", required = false) String reqid, @RequestHeader(required = false) String lang,
            @RequestBody JSONObject paramsObj) {
        Map<String, Object> paramsMap = new HashMap<String, Object>();
        paramsMap.put("page", null == paramsObj.getString("page") ? "1" : paramsObj.getString("page"));// 当前页码 默认第一页
        paramsMap.put("rows", null == paramsObj.getString("rows") ? "20" : paramsObj.getString("rows"));// 每页显示记录数 默认20条

        return testService.getData(paramsMap);
    }

serviceImpl层:

  ResponsePageVO getData(Map<String, Object> paramsMap){
        int page = Integer.parseInt(paramsMap.get("page").toString());// 当前页码

        String code = "1";
        String message = "成功";

        List<Map<String, Object>> list = this.getTestDataPagedQuery(paramsMap);

        Map<String, Object> resultMap = new HashMap<String, Object>();
        resultMap.put("data", list);
        ResponsePageVO resultVo = new ResponsePageVO();
        resultVo.setResult(code);
        resultVo.setMsg(message);
        resultVo.setPage(page);
        resultVo.setRecords(Integer.parseInt(paramsMap.get("records").toString()));
        resultVo.setTotalPages(Integer.parseInt(paramsMap.get("totalPages").toString()));
        resultVo.setTotal(Integer.parseInt(paramsMap.get("totalRecords").toString()));
        resultVo.setRows(resultMap);
        return resultVo;
  }

上面的ResponsePageVO只是一个实体类,里面声明了一些属性,用Map<String, Object>自己put相关属性也可以。

分页参数补充及查询

private List<Map<String, Object>> getTestDataPagedQuery(Map<String, Object> paramsMap) {
        int page = Integer.parseInt(paramsMap.get("page").toString());// 当前页
        int rows = Integer.parseInt(paramsMap.get("rows").toString());// 一页条数
        int beginNum = page * rows - rows;
        int endNum = page * rows;
        int totalRecords = 0;// 总条数
        int totalPages = 0;// 总页数
        paramsMap.put("beginNum", beginNum);
        paramsMap.put("endNum", endNum);
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        list = testMapper.getTestData(paramsMap);
        if (list.size() > 0) {
            totalRecords = Integer.parseInt(list.get(0).get("totalRecords").toString());
            if (totalRecords > rows) {
                if (((double) totalRecords / (double) rows) > (double) (totalRecords / rows)) {
                    totalPages = totalRecords / rows + 1;
                } else {
                    totalPages = totalRecords / rows;
                }
            } else {
                totalPages = 1;
            }
        }
        paramsMap.put("totalPages", totalPages);// 总页数
        paramsMap.put("totalRecords", totalRecords);// 总条数
        paramsMap.put("records", list.size());//当前页总条数
        return list;
    }

sql里查询的时候带一下总条数就可以了

<select id="getTestData" resultType="java.util.HashMap">
    select t.*,r.totalRecords from test t
    left join (select count(1) totalRecords from test) r on 1=1
    limit #{beginNum},#{endNum}
</select>

也可以从数据库后台分页查询并插入其他表

先查到总数,再声明每页条数,算出总页数,分页查询并插入,从而解决因数据量太大,一下查出造成的内存溢出问题。

/**
     * 分页插入
     * @param paramsMap
     */
    private void insertAllRecordPaged(Map<String, Object> paramsMap) {
        List<Map<String, Object>> codeTotalCountList = new ArrayList<Map<String,Object>>();
        codeTotalCountList = iActivityMapper.getVersionRecordTotalCountListByDaTypeId(paramsMap);
        int totalRecords = 0;//总数
        int rows = 5000;//每页5000条
        int totalPages = 0;//总页数
        if(codeTotalCountList.size() > 0) {
            totalRecords = Integer.parseInt(codeTotalCountList.get(0).get("totalRecords").toString());
        }
        if(totalRecords > 0) {
            if (totalRecords > rows) {
                if (((double) totalRecords / (double) rows) > (double) (totalRecords / rows)) {
                    totalPages = totalRecords / rows + 1;
                } else {
                    totalPages = totalRecords / rows;
                }
            } else {
                totalPages = 1;
            }
        }
        
        paramsMap.put("totalRecords", totalRecords);
        paramsMap.put("totalPages", totalPages);
        paramsMap.put("rows", rows);
        for(int i = 0; i < totalPages; i++) {
            paramsMap.put("page", (i+1));//第几页
            List<Map<String, Object>> versionRecordList = this.getVersionRecordPagedQuery(paramsMap);
            if (versionRecordList.size() > 0) {
                paramsMap.put("listAll", versionRecordList);
                iActivityMapper.insertUpgradeRecord(paramsMap);
            }
        }
    }
List<Map<String, Object>> getVersionRecordPagedQuery(Map<String, Object> paramsMap){
        int page = Integer.parseInt(paramsMap.get("page").toString());// 当前页
        int rows = Integer.parseInt(paramsMap.get("rows").toString());// 一页条数
        int beginNum = page * rows - rows;
        int endNum = page * rows;
        paramsMap.put("beginNum", beginNum);
        paramsMap.put("endNum", endNum);
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        list = testMapper.getTestData(paramsMap);
        return list;
}

总结:

分页查询只要设定好了page:第几页,rows:每页显示的条数,从而算出beginNum和endNum,查询得到总数totalRecords,根据totalRecords和rows就能算出总页数,思路还是比较简单。

相关文章

网友评论

      本文标题:java后台分页算法小记

      本文链接:https://www.haomeiwen.com/subject/dlgxvktx.html