规范说明:PageHelper 分页查询

PageHelper分页查询规范说明

1. 规范目的

为统一项目中PageHelper分页查询的开发标准,规避分页异常、类型转换错误、查询逻辑混乱等问题,确保分页查询高效、稳定、可维护,明确分页查询的技术实现要求、参数规范、逻辑约束及异常处理,适用于项目中所有分页查询场景,同时适配SQL Server 2008 R2数据库及MyBatis-Plus框架。

2. 适用范围

本规范适用于项目中所有基于PageHelper的分页查询接口开发,包括但不限于操作日志、系统日志、业务日志、用户管理等模块的分页查询,涵盖多条件筛选、日期范围查询、分页参数控制等核心场景。

3. 核心技术依赖

  • 分页组件:PageHelper(版本需与MyBatis-Plus兼容,避免版本冲突)

  • ORM框架:MyBatis-Plus(用于构建查询条件,避免硬编码SQL)

  • 数据转换:自定义Bean转换工具(用于实体与响应VO的转换)

  • 数据库:SQL Server 2008 R2(适配分页语法、日期类型处理)

4. 分页查询核心编写规范

4.1 分页参数规范

分页参数需统一封装,避免零散传递,参数定义及校验要求如下:

// 分页查询请求参数封装(必选)
public class PageQueryRequest {
    // 页码(必填,默认1,最小值1)
    @NotNull(message = "页码不能为空")
    private Integer page = 1;
    // 每页条数(必填,默认10,范围1-100)
    @NotNull(message = "每页条数不能为空")
    @Min(value = 1, message = "每页条数不能小于1")
    @Max(value = 100, message = "每页条数不能超过100")
    private Integer size = 10;
    // 日期范围-开始时间(可选)
    private LocalDateTime beginTime;
    // 日期范围-结束时间(可选)
    private LocalDateTime endTime;
    // 其他业务查询参数(如日志类型、用户名等,按需添加)
}
​

说明:分页参数必须添加校验,防止非法参数(如页码为0、负数,每页条数超出范围)导致分页失效或报错。

4.2 分页初始化规范

分页初始化必须在查询操作之前执行,严格遵循“分页初始化→查询→结果处理”的顺序,禁止颠倒执行,避免分页失效。PageHelper提供两种常用分页写法,优先推荐简洁版Lambda写法,两种写法规范如下:

4.2.1 简洁版(推荐):Lambda表达式自动组装分页

// 1、启动分页 + 查询列表,自动组装,使用Lambda表达式(更简洁)
PageInfo<Log> page = PageHelper.startPage(queryRequest.getPage(), queryRequest.getSize())
        .doSelectPageInfo(() -> logMapper.selectList(wrapper));
​

写法总结:该写法将分页初始化与查询逻辑通过Lambda表达式绑定,PageHelper.startPage()初始化分页参数后,直接调用doSelectPageInfo()方法,传入查询逻辑(logMapper.selectList(wrapper)),自动执行分页查询并封装为PageInfo对象,无需手动创建PageInfo实例,代码更简洁、优雅,且能从根源避免分页逻辑与查询逻辑分离导致的异常,是项目中优先推荐的分页写法。核心优势的是:代码简洁、无冗余,分页与查询强绑定,减少手动操作,降低类型转换异常风险。

4.2.2 基础版:手动组装分页

// 1. 启用分页
PageHelper.startPage(queryRequest.getPage(), queryRequest.getSize());
// 2. 查询列表
List<Log> logs = logMapper.selectList(wrapper);
// 3. 转换成分页,使用PageInfo包装查询结果
PageInfo&lt;Log&gt; page = new PageInfo<>(logs);
​

说明:该写法步骤清晰,适用于复杂查询场景(如多表关联、自定义SQL查询),需注意查询列表与分页初始化的顺序,禁止颠倒。

禁止写法:先执行查询,再调用PageHelper.startPage(),会导致分页不生效,返回全部数据。

4.3 分页查询逻辑规范

分页查询需包含“条件构建→分页初始化→查询执行→结果转换”四个核心步骤,结合推荐的Lambda简洁写法,完整逻辑如下:

// 步骤1:构建查询条件(MyBatis-Plus LambdaQueryWrapper)
LambdaQueryWrapper<Log> wrapper = Wrappers.lambdaQuery();
// 绑定查询条件(如日志类型、IP、描述等,按需添加)
wrapper.eq(StringUtils.isNotBlank(logType), Log::getLogType, logType)
       .like(StringUtils.isNotBlank(description), Log::getDescription, description)
       .between(Objects.nonNull(beginTime) && Objects.nonNull(endTime), 
                Log::getCreateTime, beginTime, endTime)
       .orderByDesc(Log::getId);
​
// 步骤2:分页初始化+查询执行(推荐Lambda简洁写法)
PageInfo<Log> page = PageHelper.startPage(queryRequest.getPage(), queryRequest.getSize())
        .doSelectPageInfo(() -> logMapper.selectList(wrapper));
​
// 步骤3:分页结果封装与VO转换
List<LogResponse> responseList = BeanConvertUtils.convertList(page.getList(), logConverter::toResponse);
​

4.4 分页结果处理规范

分页结果需通过PageInfo封装,禁止直接对VO列表进行强转,避免类型转换异常,核心要求如下:

  • 原始查询结果通过PageInfo封装,获取总条数、当前页数据等分页信息,无论使用哪种分页写法,最终均需通过PageInfo获取分页相关数据;

  • VO转换需在PageInfo获取结果(page.getList())后执行,确保分页数据不丢失;

  • 返回结果需包含“总条数、当前页数据”,格式统一为:

// 分页结果返回封装(标准格式)
public PageResult<LogResponse> getPageResult(PageInfo<Log> pageInfo) {
    List<LogResponse> responseList = BeanConvertUtils.convertList(pageInfo.getList(), logConverter::toResponse);
    return new PageResult<>(pageInfo.getTotal(), responseList);
}
​

5. 特殊场景处理规范

5.1 日期范围分页(重点)

当分页查询包含日期范围时,需先对日期参数进行处理,确保分页查询的时间范围准确,规范如下:

// 1. 处理前端传入的日期(LocalDate),转换为LocalDateTime
if (Objects.nonNull(dateBegin)) {
    // 开始时间:当天00:00:00
    beginTime = dateBegin.atStartOfDay();
}
if (Objects.nonNull(dateEnd)) {
    // 结束时间:当天23:59:59.999
    endTime = dateEnd.atTime(23, 59, 59, 999);
}
// 2. 绑定日期范围条件
wrapper.between(Objects.nonNull(beginTime) && Objects.nonNull(endTime),
                Log::getCreateTime, beginTime, endTime);
​

5.2 分页异常处理规范

需捕获分页相关异常,避免因参数错误、数据库异常导致接口崩溃,规范写法:

try {
    // 分页查询逻辑(推荐使用Lambda简洁写法)
    PageInfo<Log> page = PageHelper.startPage(queryRequest.getPage(), queryRequest.getSize())
            .doSelectPageInfo(() -> logMapper.selectList(wrapper));
} catch (ClassCastException e) {
    // 处理类型转换异常(如Page强转失败)
    log.error("分页查询类型转换异常:{}", e.getMessage());
    throw new BusinessException("分页查询失败,请检查参数");
} catch (Exception e) {
    log.error("分页查询异常:{}", e.getMessage());
    throw new BusinessException("系统异常,分页查询失败");
}
​

6. 禁止事项(必遵循)

  • 禁止先转换VO再进行分页强转,需先通过PageInfo封装原始查询结果,再转换VO;

  • 禁止分页初始化在查询之后执行,否则分页失效,返回全部数据;

  • 禁止不判空直接使用分页参数,需校验页码、每页条数的合法性;

  • 禁止使用硬编码SQL进行分页,必须通过MyBatis-Plus + PageHelper实现,确保兼容性;

  • 禁止忽略日期格式处理,避免因时间精度问题导致分页查询数据遗漏;

  • 禁止在复杂查询场景中随意拆分分页与查询逻辑,优先使用Lambda简洁写法(doSelectPageInfo),减少异常风险。

7. 可复用性要求

分页查询逻辑需抽离为通用方法,可复用至所有分页场景,结合推荐的Lambda简洁写法,示例:

// 通用分页查询方法(可复用,推荐Lambda写法)
private <T> PageInfo<T> getPageResult(Integer page, Integer size, LambdaQueryWrapper<T> wrapper) {
    return PageHelper.startPage(page, size)
            .doSelectPageInfo(() -> logMapper.selectList(wrapper));
}
​

8. 验证标准

分页查询编写完成后,需满足以下验证条件,确保符合规范:

  • 分页初始化正常,页码、每页条数生效,返回数据符合分页范围;

  • 无ClassCastException、NullPointerException等分页相关异常;

  • 分页总条数(total)准确,与数据库实际数据一致;

  • 日期范围、多条件筛选与分页结合正常,无数据遗漏或错误;

  • 优先使用Lambda简洁写法(doSelectPageInfo),代码无冗余、逻辑清晰。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值