CRUD仔, 如何简化分页过程

100 阅读2分钟

常规用法

controller & service中接收分页参数的几种方式

我目前发现的常见的开源框架有如下几种

@RestController
@RequestMapping("temp")
@RequiredArgsConstructor
public class TempController {
    /**
     * controller中直接接收页码也分页大小界面
     */
    @GetMapping("fn1")
    public void fn1(Integer pageNum, Integer pageSize) {
    }

    /**
     * 创建实体类接收
     */
    @GetMapping("fn2")
    public void fn2(PageQuery pageQuery) {
    }

    /**
     * 创建实体类, 类中有分页的构造方法等
     */
    @GetMapping("fn3")
    public void fn3(PageQuery pageQuery) {
    }
}

这样写起来不太方便, 原因如下:

  1. controller中原样接收, 每次都需要写这几个入参
  2. 分页参数pageNum/pageSize固定, 代码复制不方便
  3. 添加限制不方便, 如限制分页最大100页, 每页最多100条
  4. fn1就更不好了, 参数名写错了不好排查

推荐方案

为此我推荐我一直在用的一种方法:

/**
 * controller中无需接分页相关参数, 只需要接收查询条件即可
 */
@GetMapping("fn4")
public Page<Temp> fn4(TempQuery query) {
    return tempService.search(query);
}

Service中调用自己封装的静态方法

/**
 * 使用PageHelper的话, 只需要用Paging.startPage替换掉原来的PageHelper.startPage()即可
 */
public Page<Temp> search(TempQuery query){
	Paging.startPage();
	return userMapper.search(query);
}
/**
 * 使用mybatis-plus的分页插件, 需要将构造分页的new Page<T>()改为PageHelper.startPage()
 */
public Page<Temp> search(TempQuery query){
    return this.page(Paging.startPage());
}

实现方式

Paging 类 for PageHelper:

@Slf4j
public class Paging {
    public static <T> Page<T> startPage() {
        // 此为静态获取HttpServletRequest的方法, 建议封装工具类, 此处为了演示, 故而如此处理
        HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
        Page<T> page;
        try {
            String pageNum = request.getParameter("pageNum");
            String pageSize = request.getParameter("pageSize");
            if (pageNum == null) {
                pageNum = "0";
            }
            if (pageSize == null) {
                pageSize = "10";
            }
            // 这里可以限制pageSize/pageNum大小, 还可以处理一下排序等
            page = PageHelper.startPage(Integer.parseInt(pageNum), Integer.parseInt(pageSize));
        } catch (Exception e) {
            log.error("获取分页信息失败, 使用默认值", e);
            page = PageHelper.startPage(1, 10);
        }
        // 分页合理化
        page.reasonable(true);
        return page;
    }
}

Paging 类 for MybatisPlus 分页插件:

@Slf4j
public class Paging {
    public static <T> Page<T> startPage() {
        // 推荐封装的spring请求上下文工具类, 内容见上方
        HttpServletRequest request = RequestContextUtil.getRequest();
        Page<T> page;
        try {
            String pageNum = request.getParameter("pageNum");
            String pageSize = request.getParameter("pageSize");
            if (pageNum == null) {
                pageNum = "1";
            }
            if (pageSize == null) {
                pageSize = "10";
            }
            // 这里可以限制pageSize/pageNum大小, 还可以处理一下排序等内容
            page = new Page<>(Integer.parseInt(pageNum), Integer.parseInt(pageSize));
        } catch (Exception e) {
            log.error("获取分页信息失败, 使用默认值", e);
            page = new Page<>(1, 10);
        }
        return page;
    }
}

感悟

官方提供用法的demo一般仅仅是保证能用, 而不是给出最合理的代码书写方案, 因此官方写法并不一定优雅

受教程影响最深的可能就是新人写项目, 里面的类名还充斥中大量的"MyXxxUtil"/"MyXxxxConfig"