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

目录表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_idLEFT JOIN subjects su ON su.id = s.subject_idGROUP BY u.`name`;
但是这么做有个缺点,当科目数据是动态的时候,那么上面行专列的SQL就失效了 。因此,行转列的这一部分数据也得改成动态数据才行 。

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

文章插图
1 代码实现
依照行专列的这个思想,我们可以先查询所有的科目数据,然后将科目数据作为行专列的参数,然后来查询表格内容 。
public StatDTO table() {StatQuery query = new StatQuery();StatDTO statDTO = new StatDTO();// 查询所有科目(表头)Map subjectsMap = subjectsMapper.queryAll();statDTO.setHeaders(subjectsMap);// 设置表头参数,用作表头的行专列query.setSubjects(new ArrayList<>(subjectsMap.values()));// 表格内容数据查询List> contents = usersMapper.query(query);statDTO.setContents(contents);return statDTO;}
2 动态表头获取
将表头转为map,主要是方便前端处理表头和数据的映射关系,这里的Map的键将作为表格内容映射的依据 。
// subjectsMapper#mapper@MapKey("id")Map queryAll();// subjectsMapper#xmlid="queryAll" resultType="mybatisreading.domain.Subjects">selectid, namefrom test.subjects
实体数据:
@Datapublic class Subjects implements Serializable {private Integer id;private String name;// 用于设置一个字符串类型的对应关系,如果ID本身就是字符串(UUID),这一步可以省略public String getSubjectId() {return "subject" + id;}}
3 表格内容获取
动态行专列的注意点:
获取完整表格内容的源码如下:
# usersMapper#mapperList> query(StatQuery query);# usersMapper#xmlid="query" resultType="java.util.LinkedHashMap">SELECT *FROM(SELECTu.`name`,MAX(case su.id when #{item.id} then s.score else 0 end) AS ${item.subjectId},(MAX(case su.id when #{item.id} then s.score else 0 end)) totalFROM users uLEFT JOIN score s ON u.id = s.user_idLEFT JOIN subjects su ON su.id = s.subject_idGROUP BY u.`name`) rORDER BY ${subjectId}ORDER BY ${subjectId} DESC
查询参数内容如下:
【动态行专列【Mybatis实例】实现动态表头数据 、对动态表头字段排序】@Datapublic class StatQuery {/*** 科目ID 这里要使用string 数字无法作为表头名*/private String subjectId;/*** 0 DESC1 AES*/private Integer sort;private List