美文网首页
Mysql查询动态行转动态列,并使用mybatis执行导出

Mysql查询动态行转动态列,并使用mybatis执行导出

作者: AC编程 | 来源:发表于2021-10-26 13:59 被阅读0次

    一、代码

    1.1 Controller
      @GetMapping("/export")
        @ApiOperation(value="导出excel")
        public void export(QuerySurveyAnswerVO vo, HttpServletResponse response) {
            Survey survey = surveyService.get(vo.getSurveyId());
            String filename = survey.getSurveyName()+"(答卷汇总)"+".xlsx";
            List<LinkedHashMap<String, String>> datas = surveyAnswerService.listExportDatas(vo);
            ExcelWriter writer = ExcelUtil.getWriter(true);
            //设置列宽
            writer.setColumnWidth(-1, 18);
            writer.setOnlyAlias(true);
            writer.write(datas, true);
            super.exportExcel(response, writer, filename);
        }
    
    1.2 查询参数VO
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    @SuppressWarnings("serial")
    @ApiModel(value = "QuerySurveyAnswerVO")
    public class QuerySurveyAnswerVO {
    
        @ApiModelProperty(value = "调查问卷ID")
        private Long surveyId;
    
        @ApiModelProperty(value = "账号")
        private String markId;
    
        @ApiModelProperty(value = "昵称")
        private String nickName;
    
        @ApiModelProperty(value = "手机号码")
        private String mobile;
    
        @ApiModelProperty(value = "状态(0=全部;1=登录用户;2=游客)")
        private Integer anonymousState;
    }
    
    1.3 service
    public interface SurveyAnswerService {
         /**
         * 导出数据列表
         * @param vo
         * @return
         */
        List<LinkedHashMap<String, String>> listExportDatas(QuerySurveyAnswerVO vo);
    }
    
    @Override
        public List<LinkedHashMap<String, String>> listExportDatas(QuerySurveyAnswerVO vo) {
            //获取动态拼接sql
            String dynamicQuestions = mapper.dynamicQuestions(vo.getSurveyId());
    
            log.info("dynamicQuestions:"+dynamicQuestions);
    
            String markIdSql = "";
            String nickNameSql = "";
            String mobileSql = "";
            String anonymousStateSql = "";
    
            if (StringUtil.isNotEmpty(vo.getMarkId())) {
                markIdSql = " and a.mark_id like '%" + vo.getMarkId() + "%'";
            }
    
            if (StringUtil.isNotEmpty(vo.getNickName())) {
                nickNameSql = " and a.nick_name like '%" + vo.getNickName() + "%'";
            }
    
            if (StringUtil.isNotEmpty(vo.getMobile())) {
                mobileSql = " and a.mobile like '%" + vo.getMobile() + "%'";
            }
    
            if (vo.getAnonymousState() != null) {
                if (vo.getAnonymousState() == 1) {
                    anonymousStateSql = " and a.member_id is not null ";
                }
    
                if (vo.getAnonymousState() == 2) {
                    anonymousStateSql = " and a.member_id is null ";
                }
            }
    
            //手动与固定列拼接
            String sql = "select a.mark_id as 用户ID," +
                    "if(a.mark_id='',\"游客\",a.nick_name) as 用户昵称," +
                    "a.mobile as 手机号," +
                    "case a.sex" +
                    " when 'MEN' then '男' " +
                    " when 'WOMEN' then '女' " +
                    " when 'UNKNOW' then '保密' " +
                    " end as 性别," +
                    "a.answer_time as 参与时间," +
                    dynamicQuestions +
                    " from t_survey_answer_item ai JOIN t_survey_answer a on ai.survey_answer_id = a.id " +
                    " where ai.deleted=0 and a.deleted=0 and a.survey_id='" + vo.getSurveyId() + "'" +
                    markIdSql +
                    nickNameSql +
                    mobileSql +
                    anonymousStateSql +
                    " group by a.mark_id,a.nick_name,a.mobile,a.sex,a.answer_time" +
                    " order by a.answer_time desc";
    
            log.info("export sql :"+sql);
    
            //查询结果
            List<LinkedHashMap<String, String>> mapList = mapper.listExportDatas(sql);
            return mapList;
        }
    
    
    1.4 mybaits-mapper
    public interface SurveyAnswerMapper extends BaseMapper<SurveyAnswer> {
    
        /**
         * 题目集合(动态)
         * @return
         */
        String dynamicQuestions(@Param("surveyId")Long surveyId);
    
        /**
         * 导出数据列表
         * @param sql
         * @return
         */
        List<LinkedHashMap<String, String>> listExportDatas(String sql);
    }
    
    1.5 mybaits.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="com.alanchen.mapper.SurveyAnswerMapper">
    
        
        <select id="dynamicQuestions" resultType="java.lang.String">
            SELECT
             @sql :=GROUP_CONCAT(DISTINCT
              CONCAT(
               'Max(IF(ai.question_name = ''',
               a.question_name,
               ''', ai.item_name, '''')) AS ''',
               replace(a.question_name,'.',''), ''''
              )
               order by order_number asc
             )
            FROM (SELECT DISTINCT question_name,order_number FROM t_survey_question where deleted = 0 and survey_id=#{surveyId}) a,
            (SELECT @sql:="") s
        </select>
    
        <select id="listExportDatas" parameterType="java.lang.String" resultType="java.util.LinkedHashMap">
           ${sql}
        </select>
    
    </mapper>
    
    

    三、数据表结构

    CREATE TABLE `t_survey` (
      `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
      `survey_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '问卷ID',
      `survey_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '问卷标题',
      `remark` varchar(200) NOT NULL DEFAULT '' COMMENT '问卷描述',
      `publish_status` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'NOT_ENABLED' COMMENT '状态',
      `active` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否立即启用',
      `anonymous` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否匿名',
      `date_start` datetime DEFAULT NULL COMMENT '开始日期',
      `date_end` datetime DEFAULT NULL COMMENT '结束日期',
      `publisher_id` bigint DEFAULT NULL COMMENT '发布者ID',
      `publisher_name` varchar(50) DEFAULT '' COMMENT '发布者名字',
      `join_number` int DEFAULT '0' COMMENT '参与人数',
      `link_url` varchar(100) DEFAULT NULL COMMENT '访问链接',
      `question_num` int DEFAULT '0' COMMENT '题目数',
      `deleted` bit(1) NOT NULL DEFAULT b'0',
      `modify_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP,
      `create_time` datetime NOT NULL,
      PRIMARY KEY (`id`),
      KEY `IDX_deleted` (`deleted`)
    ) ENGINE=InnoDB AUTO_INCREMENT=186831853387778 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci AVG_ROW_LENGTH=2048 COMMENT='问卷调查'
    
    
    CREATE TABLE `t_survey_answer` (
      `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
      `survey_id` bigint NOT NULL DEFAULT '0' COMMENT '问卷ID',
      `member_id` bigint DEFAULT NULL COMMENT '会员ID',
      `mobile` char(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '手机号码',
      `nick_name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '昵称',
      `mark_id` varchar(22) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '账号',
      `icon_url` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT '' COMMENT '用户头像地址',
      `sex` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '用户性别 UNKNOW保密 MEN男 WOMEN女',
      `answer_time` datetime DEFAULT NULL COMMENT '答题时间',
      `deleted` bit(1) NOT NULL DEFAULT b'0',
      `modify_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP,
      `create_time` datetime NOT NULL,
      PRIMARY KEY (`id`),
      KEY `IDX_deleted` (`deleted`)
    ) ENGINE=InnoDB AUTO_INCREMENT=189434090356738 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci AVG_ROW_LENGTH=2048 COMMENT='用户答卷'
    
    
    CREATE TABLE `t_survey_answer_item` (
      `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
      `survey_id` bigint NOT NULL DEFAULT '0' COMMENT '问卷ID',
      `survey_answer_id` bigint NOT NULL DEFAULT '0' COMMENT '用户答卷ID',
      `question_id` bigint NOT NULL DEFAULT '0' COMMENT '题目ID',
      `question_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '题目名称',
      `serial_number` int DEFAULT '0',
      `question_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'SINGLE_CHOICE' COMMENT '题型',
      `question_item_id` bigint DEFAULT NULL COMMENT '选项ID',
      `item_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '选项内容',
      `icon` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '图标',
      `order_number` int DEFAULT '0',
      `deleted` bit(1) NOT NULL DEFAULT b'0',
      `modify_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP,
      `create_time` datetime NOT NULL,
      PRIMARY KEY (`id`),
      KEY `IDX_deleted` (`deleted`)
    ) ENGINE=InnoDB AUTO_INCREMENT=189434090356743 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci AVG_ROW_LENGTH=2048 COMMENT='用户答卷明细'
    
    
    CREATE TABLE `t_survey_question` (
      `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
      `survey_id` bigint NOT NULL DEFAULT '0' COMMENT '问卷ID',
      `question_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '题目名称',
      `question_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'SINGLE_CHOICE' COMMENT '题型',
      `required` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否必填',
      `least` int DEFAULT NULL COMMENT '最少选择',
      `most` int DEFAULT NULL COMMENT '最多选择',
      `order_number` int DEFAULT '0' COMMENT '排序序号',
      `forward_order_number` int DEFAULT NULL COMMENT '跳题序号(多选题时)',
      `forward_question_id` bigint DEFAULT NULL COMMENT '跳题ID(多选时)',
      `serial_number` int DEFAULT '0',
      `deleted` bit(1) NOT NULL DEFAULT b'0',
      `modify_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP,
      `create_time` datetime NOT NULL,
      PRIMARY KEY (`id`),
      KEY `IDX_deleted` (`deleted`)
    ) ENGINE=InnoDB AUTO_INCREMENT=186887039942735 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci AVG_ROW_LENGTH=2048 COMMENT='问卷调查题目'
    
    
    CREATE TABLE `t_survey_question_item` (
      `id` bigint NOT NULL AUTO_INCREMENT COMMENT 'ID',
      `survey_id` bigint NOT NULL DEFAULT '0' COMMENT '问卷ID',
      `question_id` bigint NOT NULL DEFAULT '0' COMMENT '题目ID',
      `item_name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT '' COMMENT '选项内容',
      `icon` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '图标',
      `item_type` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL DEFAULT 'TEXT' COMMENT '类型',
      `order_number` int DEFAULT '0' COMMENT '排序序号',
      `forward_order_number` int DEFAULT NULL COMMENT '跳题序号',
      `forward_question_id` bigint DEFAULT NULL COMMENT '跳题ID',
      `deleted` bit(1) NOT NULL DEFAULT b'0',
      `modify_time` datetime NOT NULL ON UPDATE CURRENT_TIMESTAMP,
      `create_time` datetime NOT NULL,
      PRIMARY KEY (`id`),
      KEY `IDX_deleted` (`deleted`)
    ) ENGINE=InnoDB AUTO_INCREMENT=186887039942742 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci AVG_ROW_LENGTH=2048 COMMENT='题目选项'
    
    

    四、MySQL GROUP_CONCAT函数长度限制

    平常使用可能发现不了问题,在处理大数据的时候,会发现内容被截取了,其实MYSQL内部对这个是有设置的,默认不设置的长度是1024个字符,如果我们需要更大,就需要手工去修改配置。

    1、查看当前mysql group_concat_max_len

    show variables like 'group_concat_max_len'
    

    2、如果不方便重启mysql 可以在mysql状态通过命令设置,如

    SET GLOBAL group_concat_max_len=102400;
    SET SESSION group_concat_max_len=102400;
    

    此种方式在mysql重启后会读取配置文件重新设置,会导致设置失效,所以建议依旧要修改配置文件。

    3、修改配置文件:my.ini
    在[mysqld]下新增配置:group_concat_max_len = 102400
    重启,通过方式1查看即可。

    4、不限制大小
    有时我们并不知需要多大的字节才能满足需求,此种情况可以考虑不设置最大字节(即采用最大字节数)即在配置文件设置group_concat_max_len=-1

    五、备注

    1、导出用的是Hutool导出工具类

    六、参考资料

    mysql查询动态行转动态列,并使用mybatis执行

    MySQL 动态 行转列(列值转换列名)

    相关文章

      网友评论

          本文标题:Mysql查询动态行转动态列,并使用mybatis执行导出

          本文链接:https://www.haomeiwen.com/subject/hezealtx.html