🎉工作中遇到这样一个需求场景:实现一个统计查询,要求可以根据用户在前端界面筛选的字段进行动态地分组统计。也就是说,后端在实现分组查询的时候,Group By 的字段是不确定的,可能是一个字段、多个字段或者不进行分组查询,这都是由用户在前端决定的。
💡这里给出的实现方案:
- 前端界面收集用户需要分组统计的字段,然后将这些字段名组成一个字符串,字段名之间由逗号分隔,传递给后端。
- 后端拿到分组字段名字符串再根据逗号分隔符进行处理,拼装成一个分组字段名列表。
- 最后,利用 Mybatis 框架的动态 SQL 语句,实现动态分组字段的统计查询。
控制类
XxxStatisticsController
实现代码如下:
@RestController@RequestMapping("/statistics")publicclassXxxStatisticsController{@AutowiredprivateXxxService xxxService;@Operation(method =GET_METHOD, summary ="xxx动态分组统计直方图", parameters ={@Parameter(name ="startDate", description ="开始日期,形如:2023-07-01"),@Parameter(name ="endDate", description ="结束日期,形如:2023-07-10"),@Parameter(name ="groupFields", description ="需要分组的字段名称,逗号分隔,形如“level,title”"),@Parameter(name ="title", description ="标题")})@Login@GetMapping("/xxxStatistics")publicResult<Map<String,List<StatisticsDO>>>xxxStatistics(@RequestParamString startTime,@RequestParamString endTime,@RequestParam(required =false)String groupFields,@RequestParam(required =false)String title){QueryBuilder builder =QueryBuilder.page(0).pageSize(1);// 此处省略若干代码if(StringUtils.isNotBlank(groupFields)){List<String> groupFieldList =Arrays.asList(groupFields.split(Constants.COMMA_SPLIT));
builder.put("groupFieldList", groupFieldList);}return xxxService.xxxStatistics(builder.build());}}
xxx-statistics-info-mapper.xml
文件代码如下:
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPEmapperPUBLIC"-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mappernamespace="XxxStatisticsInfoMapper"><resultMapid="default"type="XxxStatisticsInfoDO"><resultcolumn="id"property="id"/><resultcolumn="title"property="title"/><resultcolumn="xxx"property="xxx"/><resultcolumn="xxx"property="xxx"/><resultcolumn="xxx"property="xxx"/><resultcolumn="xxx"property="xxx"/><resultcolumn="xxx"property="xxx"/><resultcolumn="xxx"property="xxx"/><resultcolumn="create_time"property="createTime"/><resultcolumn="update_time"property="updateTime"/></resultMap><sqlid="query"><iftest="startTime != null and startTime != ''">
AND alert_time >= #{startTime}
</if><iftest="endTime != null and endTime != ''">
AND alert_time <= #{endTime}
</if></sql><sqlid="queryByGroup"><iftest="groupFieldList != null and groupFieldList.size() > 0"><!-- 这里根据前端传入的参数拼接动态的 GROUP BY 子句 -->
GROUP BY
<foreachitem="field"collection="groupFieldList"separator=",">
${field}
</foreach></if></sql><selectid="dynamicGroupStatistics"resultType="com.xxx.xxx.domain.DynamicGroupStatisticsDO">
SELECT
xxx,
xxx,
xxx,
title,
xxx,
xxx,
count(*) AS xxx_num
FROM xxx_statistics_info
<where><includerefid="query"/><iftest="title != null and title != ''">
AND title = #{title}
</if></where><includerefid="queryByGroup"/>
ORDER BY xxx_num DESC
LIMIT 30
</select></mapper>
版权归原作者 ReadThroughLife 所有, 如有侵权,请联系我们删除。