首页 >> 大全

【Mybatis实例】实现动态表头数据 (动态行专列)、对动态表头字段排序

2023-11-20 大全 22 作者:考证青年

目录 表DDL

动态表头(表头排序) 业务说明

现在有三张表,每个表的数据都是动态变化的:科目表()、用户表(users)、分数表(score)

由于业务需要,现在要将科目信息作为表头,用户作为表的行数据,每行显示的是用户对应科目的分数,并且要支持对表头的每个科目和总分进行排序。

内容如下图:

实现

一般来说,动态表头都可以通过实现行专列来实现。

行专列SQL示例:

SELECT u.`name`, MAX(CASE su.`name` WHEN 'java' THEN s.score END ) `java`,MAX(CASE su.`name` WHEN 'C' THEN s.score END ) `C`,MAX(CASE su.`name` WHEN 'C#' THEN s.score END ) `C#`,MAX(CASE su.`name` WHEN 'Python' THEN s.score END ) `Python`
FROM users u 
LEFT JOIN score s ON u.id = s.user_id
LEFT JOIN subjects su ON su.id = s.subject_id
GROUP BY u.`name`;

但是这么做有个缺点,当科目数据是动态的时候,那么上面行专列的SQL就失效了。因此,行转列的这一部分数据也得改成动态数据才行。

excel动态表头_如何表头不动进行排序_

1 代码实现

依照行专列的这个思想,我们可以先查询所有的科目数据,然后将科目数据作为行专列的参数,然后来查询表格内容。

public StatDTO table() {StatQuery query = new StatQuery();StatDTO statDTO = new StatDTO();// 查询所有科目(表头)Map<Integer, Subjects> subjectsMap = subjectsMapper.queryAll();statDTO.setHeaders(subjectsMap);// 设置表头参数,用作表头的行专列query.setSubjects(new ArrayList<>(subjectsMap.values()));// 表格内容数据查询List<Map<String, Object>> contents = usersMapper.query(query);statDTO.setContents(contents);return statDTO;
}

2 动态表头获取

将表头转为map,主要是方便前端处理表头和数据的映射关系,这里的Map的键将作为表格内容映射的依据。

// subjectsMapper#mapper
@MapKey("id")
Map<Integer, Subjects> queryAll();// subjectsMapper#xml
<select id="queryAll" resultType="mybatisreading.domain.Subjects">selectid, namefrom test.subjects
select>

实体数据:

@Data
public class Subjects implements Serializable {private Integer id;private String name;// 用于设置一个字符串类型的对应关系,如果ID本身就是字符串(UUID),这一步可以省略public String getSubjectId() {return "subject" + id;}
}

3 表格内容获取

动态行专列的注意点:

获取完整表格内容的源码如下:

# usersMapper#mapper
List<String, Object>> query(StatQuery query);# usersMapper#xml
<select id="query" resultType="java.util.LinkedHashMap">SELECT *FROM(SELECTu.`name`,<foreach item="item" index="index" collection="subjects" separator=",">MAX(case su.id when #{item.id} then s.score else 0 end) AS ${item.subjectId}foreach>,(<foreach item="item" index="index" collection="subjects" separator="+">MAX(case su.id when #{item.id} then s.score else 0 end)foreach>) totalFROM users uLEFT JOIN score s ON u.id = s.user_idLEFT JOIN subjects su ON su.id = s.subject_idGROUP BY u.`name`) r<if test="subjectId != null"><choose><when test='sort != null and sort == "1"'>ORDER BY ${subjectId}when><otherwise>ORDER BY ${subjectId} DESCotherwise>choose>if>
select>

查询参数内容如下:

@Data
public class StatQuery {/*** 科目ID 这里要使用string 数字无法作为表头名*/private String subjectId;/*** 0 DESC  1 AES*/private Integer sort;private List<Subjects> subjects;
}

4 动态表头排序

代码在3中已经展示过了。动态表头的排序,相对来说比较简单,只需要使用重名命后的列名进行排序即可:

<if test="subjectId != null"><choose><when test='sort != null and sort == "1"'>ORDER BY ${subjectId}when><otherwise>ORDER BY ${subjectId} DESCotherwise>choose>if>

5 执行结果

{"headers": {"1": {"id": 1,"name": "java","subjectId": "subject1"},"2": {"id": 2,"name": "C","subjectId": "subject2"},"3": {"id": 3,"name": "C#","subjectId": "subject3"},"4": {"id": 4,"name": "Python","subjectId": "subject4"}},"contents": [{"name": "沸羊羊","subject1": 76,"subject2": 32,"subject3": 67,"subject4": 12,"total": 187},{"name": "懒羊羊","subject1": 42,"subject2": 27,"subject3": 99,"subject4": 12,"total": 180},{"name": "喜羊羊","subject1": 89,"subject2": 98,"subject3": 90,"subject4": 97,"total": 374}]
}

表DDL

CREATE TABLE `subjects` (`id` int NOT NULL,`name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '科目',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;CREATE TABLE `users` (`id` int NOT NULL,`name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;CREATE TABLE `score` (`id` int NOT NULL,`user_id` int DEFAULT NULL,`subject_id` int DEFAULT NULL,`score` tinyint DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

源码地址:

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了