zoukankan      html  css  js  c++  java
  • mybatis接受mysql存储过程out的值

    这是题目的实体类

        private Integer id;
        private Integer type;//题型    单选,多选
        private String category;//类型    数据字典配置
        private String problem;//问题
        private String choose1;//选择1
        private String choose2;
        private String choose3;
        private String choose4;
        private String choose5;
        private String choose6;
        private String choose7;
        private String choose8;
        private String answer;//答案

    卷子的实体类

        private Integer id;
        private String title;
        private String problemNo;//题目,逗号分割
        private Integer extract;//抽题个数

    需求:已经录入若干提,其中每题的类型不完全相同,例如有的题目是语文,有的是数学之类的。

    抽取其中若干题,必然是小于录入题的,必须保证每种类型的题都被抽取到,且希望能根据不同类型的题目均匀抽取;

    例如录入40题,抽取10题。

    假如语文,数学,物理,化学各是16,12,8,4。那么抽取语文,数学,物理,化学应当各是4,3,2,1道题。

    假如语文,数学,物理,化学各是19,19,1,1。那么抽取语文,数学,物理,化学应当各是4,4,1,1道题。

    作出最优解。

     表结构:

    CREATE TABLE `tb_multi_question_problem` (
      `id` int(10) NOT NULL AUTO_INCREMENT COMMENT 'ID',
      `type` tinyint(4) DEFAULT NULL COMMENT '题型',
      `category` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '类型',
      `problem` varchar(512) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '问题',
      `choose1` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '选择1',
      `choose2` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '选择2',
      `choose3` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '选择3',
      `choose4` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '选择4',
      `choose5` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '选择5',
      `choose6` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '选择6',
      `choose7` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '选择7',
      `choose8` varchar(128) COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '选择8',
      `answer` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
      `update_time` datetime DEFAULT NULL COMMENT '更新时间',
      `create_time` datetime DEFAULT NULL COMMENT '创建时间',
      `update_user` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
      `create_user` varchar(32) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
      `del_flag` char(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=58 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
    CREATE TABLE `tb_multi_questionnaire` (
      `id` int(10) NOT NULL AUTO_INCREMENT,
      `title` varchar(128) DEFAULT NULL,
      `description` text,
      `imgurl` varchar(128) DEFAULT NULL,
      `problem_no` varchar(512) DEFAULT NULL,
      `parent_area` varchar(32) DEFAULT NULL,
      `area` varchar(32) DEFAULT NULL,
      `committee` varchar(32) DEFAULT NULL,
      `start_time` datetime DEFAULT NULL,
      `end_time` datetime DEFAULT NULL,
      `duration` int(10) DEFAULT NULL COMMENT '时长',
      `number` tinyint(4) DEFAULT NULL,
      `extract` tinyint(4) DEFAULT NULL,
      `url1` varchar(256) DEFAULT NULL,
      `url2` varchar(256) DEFAULT NULL,
      `url3` varchar(256) DEFAULT NULL,
      `update_time` datetime DEFAULT NULL COMMENT '更新时间',
      `create_time` datetime DEFAULT NULL COMMENT '创建时间',
      `update_user` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
      `create_user` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL,
      `del_flag` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;

    解决方案,因为涉及到类型,且类型未均匀分布。避免多次访问数据库,使用存储过程;

    CREATE DEFINER=`root`@`localhost` PROCEDURE `rand_question`(in pid int, out idstr VARCHAR(128))
    begin
    declare pno VARCHAR(128);
    declare qp VARCHAR(32);
    DECLARE ques_ext int DEFAULT 1;
    DECLARE ques_sum int DEFAULT 0;
    DECLARE qpid VARCHAR(32);
    DECLARE qpCategory VARCHAR(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
    DECLARE qpSum INT(10);
    DECLARE q_sum INT(10) DEFAULT 0;
    DECLARE rem INT(10) DEFAULT 0;
    DECLARE lim INT(10) DEFAULT 0;
    declare done int default -1;
    DECLARE qp_cursor CURSOR FOR SELECT qp.category,COUNT(1) FROM tb_multi_question_problem qp WHERE del_flag = '0' and FIND_IN_SET(qp.id,(SELECT q.problem_no FROM tb_multi_questionnaire q WHERE del_flag = '0' and q.id = pid)) GROUP BY qp.category;
    DECLARE CONTINUE HANDLER FOR NOT found SET done = 1;
    SELECT q.problem_no INTO pno FROM tb_multi_questionnaire q WHERE del_flag = '0' and q.id = pid;
    SELECT q.extract into ques_ext FROM tb_multi_questionnaire q WHERE del_flag = '0' and q.id = pid;
    SELECT COUNT(1) into ques_sum FROM tb_multi_question_problem qp WHERE del_flag = '0' and FIND_IN_SET(qp.id,(SELECT q.problem_no FROM tb_multi_questionnaire q WHERE del_flag = '0' and q.id = pid));
    set idstr = '';
    OPEN qp_cursor;
    qpLoop : LOOP
        FETCH qp_cursor INTO qpCategory,qpSum;
        IF done = 1 THEN
        LEAVE qpLoop;
        END IF;
        set rem = floor(qpSum*ques_ext/ques_sum);
        IF rem < 1 THEN
        SET rem = 1;
        END IF;
        SELECT group_concat(id) INTO qpid FROM (SELECT id FROM tb_multi_question_problem WHERE del_flag = '0' and category = qpCategory and FIND_IN_SET(id,pno) and id >= (SELECT FLOOR(RAND()*(SELECT MAX(id) FROM tb_multi_question_problem WHERE del_flag = '0' and category = qpCategory))) order by rand() LIMIT rem) as a;
        set idstr = CONCAT(idstr,qpid,',');
    END LOOP qpLoop;
    CLOSE qp_cursor;
    select length(idstr)-length(replace(idstr,',','')) INTO q_sum;
        WHILE  q_sum < ques_ext DO
        SET lim = ques_ext-q_sum;
        SELECT ques_ext,q_sum,lim;
        SELECT group_concat(a.id) INTO qpid FROM (SELECT * FROM tb_multi_question_problem WHERE del_flag = '0' and !FIND_IN_SET(id,idstr) and id >= (SELECT FLOOR(RAND()*(SELECT MAX(id) FROM tb_multi_question_problem WHERE del_flag = '0'))) order by rand() LIMIT lim) as a WHERE FIND_IN_SET(a.id,pno);
        set idstr = CONCAT(idstr,qpid,',');
        select length(idstr)-length(replace(idstr,',','')) INTO q_sum;
        END WHILE;
    end

    得到所得的值有两种方法,第一种:

    使用map传递接受参数

    mapper.xml

    <resultMap type="java.util.HashMap" id="resultMap">
           <result column="id" property="id" javaType="java.lang.Integer" jdbcType="INTEGER"/>
           <result column="idstr" property="idstr" javaType="java.lang.String" jdbcType="VARCHAR"/>
        </resultMap>
    
        <select id="randomList" statementType="CALLABLE" parameterType="java.util.HashMap" resultMap="resultMap">
            {
                call rand_question(
                #{id,jdbcType=INTEGER,mode=IN},
                #{idstr, jdbcType=VARCHAR,mode=OUT})
            }
        </select>

    service

    public List<QuestionProblem> randomList(Map<String, Object> param) {
            questionProblemDao.randomList(param);
            return questionProblemDao.getListByIds((String)param.get("idstr"));
        }

    如上,通过param传参,也通过param接受参数;

    类似于selectkey,我之前写的博客https://www.cnblogs.com/zhengyuanyuan/p/10616616.html

    第二种通过javabean,有时间再补充

  • 相关阅读:
    pthread_once函数的简单示例
    pthread_join直接决定资源是否能够及时释放
    非分离线程未使用join函数例子:
    一个HTTP打趴80%面试者
    BM和KMP字符串匹配算法学习
    STL 几个容器的底层实现
    指针的引用(*&)与指针的指针(**)
    Maven 环境变量设置
    配置JAVA的环境变量
    Maven报错 解决方案。ERROR: No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id
  • 原文地址:https://www.cnblogs.com/zhengyuanyuan/p/10731317.html
Copyright © 2011-2022 走看看