【已解决】Mybatis 实现 Group By 动态分组查询

🎉工作中遇到这样一个需求场景:实现一个统计查询,要求可以根据用户在前端界面筛选的字段进行动态地分组统计。也就是说,后端在实现分组查询的时候,Group By 的字段是不确定的,可能是一个字段、多个字段或者不进行分组查询,这都是由用户在前端决定的。

💡这里给出的实现方案:

  • 前端界面收集用户需要分组统计的字段,然后将这些字段名组成一个字符串,字段名之间由逗号分隔,传递给后端。
  • 后端拿到分组字段名字符串再根据逗号分隔符进行处理,拼装成一个分组字段名列表。
  • 最后,利用 Mybatis 框架的动态 SQL 语句,实现动态分组字段的统计查询。

控制类XxxStatisticsController实现代码如下:

java 复制代码
@RestController
@RequestMapping("/statistics")
public class XxxStatisticsController {

    @Autowired
    private XxxService 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")
    public Result<Map<String, List<StatisticsDO>>> xxxStatistics(
    														 @RequestParam String startTime,
                                                             @RequestParam String 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 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="XxxStatisticsInfoMapper">
    <resultMap id="default" type="XxxStatisticsInfoDO">
        <result column="id" property="id"/>
        <result column="title" property="title"/>
        <result column="xxx" property="xxx"/>
        <result column="xxx" property="xxx"/>
        <result column="xxx" property="xxx"/>
        <result column="xxx" property="xxx"/>
        <result column="xxx" property="xxx"/>
        <result column="xxx" property="xxx"/>
        <result column="create_time" property="createTime"/>
        <result column="update_time" property="updateTime"/>
    </resultMap>
    
    <sql id="query">
        <if test="startTime != null and startTime != ''">
            AND alert_time &gt;= #{startTime}
        </if>
        <if test="endTime != null and endTime != ''">
            AND alert_time &lt;= #{endTime}
        </if>
    </sql>

    <sql id="queryByGroup">
        <if test="groupFieldList != null and groupFieldList.size() > 0">
            <!-- 这里根据前端传入的参数拼接动态的 GROUP BY 子句 -->
            GROUP BY
            <foreach item="field" collection="groupFieldList" separator=",">
                ${field}
            </foreach>
        </if>
    </sql>
    
    <select id="dynamicGroupStatistics" resultType="com.xxx.xxx.domain.DynamicGroupStatisticsDO">
        SELECT
        xxx,
        xxx,
        xxx,
        title,
        xxx,
        xxx,
        count(*) AS xxx_num
        FROM xxx_statistics_info
        <where>
            <include refid="query"/>
            <if test="title != null and title != ''">
                AND title = #{title}
            </if>
        </where>
        <include refid="queryByGroup"/>
        ORDER BY xxx_num DESC
        LIMIT 30
    </select>
</mapper>
相关推荐
cyt涛20 分钟前
MyBatis 学习总结
数据库·sql·学习·mysql·mybatis·jdbc·lombok
OLDERHARD5 小时前
Java - MyBatis(上)
java·oracle·mybatis
计算机学姐17 小时前
基于SpringBoot+Vue的高校运动会管理系统
java·vue.js·spring boot·后端·mysql·intellij-idea·mybatis
我是浮夸18 小时前
MyBatisPlus——学习笔记
java·spring boot·mybatis
编程、小哥哥1 天前
手写mybatis之Mapper XML的解析和注册使用
xml·java·mybatis
小桑要读研1 天前
Redis实现点赞
java·mysql·mybatis
真的想不出名儿2 天前
04-SpringBootWeb案例(下)
mybatis·spingbootweb
舞者H2 天前
如何实现Mybatis自定义插件
java·mybatis
程序员大金2 天前
基于SpringBoot+Vue+MySQL的考勤管理系统
java·javascript·vue.js·spring boot·后端·mysql·mybatis
beiback3 天前
Springboot + netty + rabbitmq + myBatis
spring boot·mysql·rabbitmq·mybatis·netty·java-rabbitmq