5.1 KiB
5.1 KiB
分页汇总功能使用说明
本文档介绍如何在平台项目中启用分页接口的汇总行(SUM)统计能力。该能力基于 PageResult 返回体与 @PageSum 标注,在分页查询时自动计算并返回指定字段的合计值。
适用场景
- 需要在分页列表底部展示金额、数量等合计值。
- 希望后端自动补充汇总信息,避免前端手动累加。
- 已使用
BaseMapperX及其selectPage等分页便捷方法。
功能概览
| 组件 | 位置 | 作用 |
|---|---|---|
@PageSum |
com.zt.plat.framework.common.annotation.PageSum |
标注需要参与 SUM 聚合的实体字段 |
PageResult.summary |
com.zt.plat.framework.common.pojo.PageResult |
承载字段 -> BigDecimal 的汇总结果 |
PageSumSupport |
com.zt.plat.framework.mybatis.core.sum.PageSumSupport |
负责扫描注解、克隆查询条件并执行 SUM 查询 |
BaseMapperX.selectPage |
com.zt.plat.framework.mybatis.core.mapper.BaseMapperX |
在分页与非分页查询后自动附加汇总信息 |
接入步骤
1. 在实体上标注 @PageSum
@TableName("order_summary")
public class OrderSummaryDO {
private Long id;
@PageSum
private BigDecimal amount;
@PageSum(column = "tax_amount")
private BigDecimal tax;
@PageSum(column = "discount")
private BigDecimal discountSummary;
// 其它字段 ...
}
- 不传
column时,默认使用 MyBatis-Plus 实体字段映射的数据库列。 - 如需跨表或函数(例如
sum(price * quantity)),可在column中直接写 SQL 片段。 - 必须是数值类型(
Number、BigDecimal、原生数值)。非数值字段会被忽略并打印警告日志。 - 对于并不存在于表中的“汇总专用字段”,仅需在
@PageSum中声明exist = false,框架会自动注入等效的@TableField(exist = false),无需再次编写@TableField注解。
2. 使用 BaseMapperX 的分页能力
PageResult<OrderSummaryRespVO> page = orderSummaryMapper.selectPage(pageParam, wrapper);
- 仅
BaseMapperX.selectPage(含排序参数版本)支持自动附加汇总结果。 - 对于
PageParam.PAGE_SIZE_NONE(不分页)场景同样有效。 selectJoinPage暂未附加汇总信息,如需支持请二次封装。
⚠️ 目前的汇总增强依赖 MyBatis-Plus 默认分页(单表/简单条件)实现聚合。若需在复杂联表或高度自定义 SQL 中进行统计,请单独编写汇总接口,或在自定义逻辑中手工调用
PageSumSupport.tryAttachSummary(...),避免影响现有查询语句。
3. 暴露响应结果
PageResult 现在包含两个与数量相关的属性:
total:分页总数量,仍通过total字段返回(向后兼容totalCount反序列化)。summary:Map 结构,键为实体字段名,值为BigDecimal类型的合计值。
示例响应:
{
"code": 0,
"data": {
"list": [
{ "id": 1, "amount": 20.00, "tax": 1.20 },
{ "id": 2, "amount": 30.00, "tax": 1.80 }
],
"total": 2,
"summary": {
"amount": 50.00,
"tax": 3.00
}
}
}
前端即可直接读取 data.summary.amount 展示汇总行,无需手工聚合。
常见问题
汇总结果为空
- 检查实体字段是否正确标注
@PageSum,且类型为数值。 - 确认 Mapper 的泛型实体与查询结果实体一致,
PageSumSupport会基于 Mapper 泛型解析实体类型。 - 若查询条件覆盖了
select列表(如显式调用select(...)),请确保 SUM 语句仍能执行;PageSumSupport会克隆 Wrapper 并重新设置select列表,手写 SQL 需保证兼容。
自定义 SQL & 复杂场景
-
对于需要复杂汇总(如 CASE WHEN),可在
column属性中写 SQL 表达式:@PageSum(column = "SUM(CASE WHEN status = 'PAID' THEN amount ELSE 0 END)") private BigDecimal paidAmount; -
当前实现 仅会扫描 Mapper 泛型实体类 上的
@PageSum标注。若分页接口最终返回 VO,请先在实体上完成标注,再使用PageResult.convert(...)或其它方式将数据转换为 VO;转换后summary内容会被完整保留。
非 BaseMapperX 查询
- 目前自动聚合只对
BaseMapperX.selectPage及分页列表查询有效。 - 若使用 XML 自定义 SQL,可在逻辑中手动调用
PageSumSupport.tryAttachSummary(mapper, wrapper, pageResult)。
调试与测试
- 单元测试示例:
com.zt.plat.framework.mybatis.core.sum.PageSumSupportTest。 - 运行
mvn -pl zt-framework/zt-spring-boot-starter-mybatis -am test可验证功能和回归。 - 日志中会输出数字解析或字段配置异常的告警信息,便于定位问题。
变更兼容性
PageResult仍通过list/total提供原有分页数据,向后兼容旧接口。- 新增
summary字段,前端可按需展示。 totalCountSetter / Getter 仍保留(@JsonIgnore),可兼容旧代码逻辑。
如需进一步扩展(例如 AVG、MAX 等聚合),可按现有结构在 PageSumSupport 基础上新增注解与聚合逻辑。