【已解决】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>
相关推荐
呼啦啦啦啦啦啦啦啦17 分钟前
【Redis】持久化机制
java·redis·mybatis
苏-言9 小时前
MyBatis最佳实践:动态 SQL
数据库·sql·mybatis
苏-言1 天前
MyBatis最佳实践:提升数据库交互效率的秘密武器
数据库·mybatis
一缕叶2 天前
mybatis(19/134)
mybatis
lozhyf2 天前
基于SpringBoot + Mybatis Plus + SaToken + Thymeleaf + Layui的后台管理系统
spring boot·layui·mybatis
坚持不懈的大白2 天前
后端:MyBatis
mybatis·pagehelper
十二同学啊2 天前
MyBatis Plus 的 InnerInterceptor:更轻量级的 SQL 拦截器
sql·tomcat·mybatis
日拱一卒无有尽, 功不唐捐终入海2 天前
Mybatis乐观锁使用
java·开发语言·jvm·mybatis
小菜日记^_^3 天前
苍穹外卖项目总结(二)
java·spring boot·spring·tomcat·maven·mybatis·postman
阑梦清川3 天前
用户中心项目教程(五)---MyBatis-Plus完成后端初始化+测试方法
java·数据库·mybatis