浏览代码

随机抽题规则查询优化,规则组和规则明细关联查询

yangfeng 2 年之前
父节点
当前提交
c87d8ef934

+ 29 - 25
web/src/main/java/com/yntravelsky/buss/exam/paper/service/impl/PaperServiceImpl.java

@@ -104,26 +104,40 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements
     @Transactional(rollbackFor = Exception.class)
     @Override
     public List<PaperQuestion> generateQuestion(String paperId) {
-        //获取规则组
-        List<PaperRuleGroup> ruleGroups = paperRuleGroupService.listByPaperId(paperId);
-        //获取规则明细
-        List<PaperRuleDetail> ruleDetails = paperRuleDetailService.listByPaperId(paperId);
+        long start = System.currentTimeMillis();
+        //获取规则组及规则明细
+        List<PaperRuleGroup> ruleGroups = paperRuleGroupService.listGroupAndDetail(paperId);
+        //从规则组中获取规则明细
+        List<PaperRuleDetail> ruleDetails = listRuleDetail(ruleGroups);
 
         //生成题目查询条件
         List<QuestionConditionDTO> dtoList = generateQuestionCondition(ruleDetails);
         //根据查询条件一次性获取题目,防止每个规则明细都查询一次,降低数据库负载,提高性能
         List<Question> ruleQuestions = questionService.listQuestionByCondition(dtoList);
 
-        //规则明细按组id分组
-        Map<String, List<PaperRuleDetail>> datailMap = ruleDetails.stream().collect(Collectors.groupingBy(PaperRuleDetail::getGroupId, Collectors.toList()));
         //按每组规则生成试题
-        Map<String, List<Question>> groupQuestionMap = generateGroupQuestionMap(ruleGroups, datailMap, ruleQuestions);
+        Map<String, List<Question>> groupQuestionMap = generateGroupQuestionMap(ruleGroups, ruleQuestions);
         //生成试卷试题
         List<PaperQuestion> paperQuestions = generatePaperQuestions(paperId, ruleGroups, groupQuestionMap);
+        log.info("生成试卷试题完成,耗时:" + (System.currentTimeMillis() - start) / 1000 + "秒");
         //试卷试题排序
         return paperQuestionService.sort(paperQuestions);
     }
 
+    /**
+     * 从规则组中获取规则明细
+     *
+     * @param ruleGroups
+     * @return
+     */
+    public List<PaperRuleDetail> listRuleDetail(List<PaperRuleGroup> ruleGroups) {
+        List<PaperRuleDetail> ruleDetails = new ArrayList<>();
+        if (!CollectionUtils.isEmpty(ruleGroups)) {
+            ruleGroups.stream().forEach(g -> ruleDetails.addAll(g.getRuleList()));
+        }
+        return ruleDetails;
+    }
+
     /**
      * 生成题目查询条件
      *
@@ -148,17 +162,15 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements
      * 按每组规则生成试题
      *
      * @param ruleGroups
-     * @param datailMap
      * @return
      */
     public Map<String, List<Question>> generateGroupQuestionMap(List<PaperRuleGroup> ruleGroups,
-                                                                Map<String, List<PaperRuleDetail>> datailMap,
                                                                 List<Question> ruleQuestions) {
         long start = System.currentTimeMillis();
-        Map<String, List<Question>> groupQuestionMap = new HashMap<>();
+        Map<String, List<Question>> groupQuestionMap = new LinkedHashMap<>();
         if (!CollectionUtils.isEmpty(ruleGroups)) {
             //根据规则明细,多线程并发生成试题
-            Map<String, FutureTask<List<Question>>> resultMap = generateQuestion(ruleGroups, datailMap, ruleQuestions);
+            Map<String, FutureTask<List<Question>>> resultMap = generateQuestion(ruleGroups, ruleQuestions);
 
             //获取试题并按分组归类
             for (Map.Entry<String, FutureTask<List<Question>>> entry : resultMap.entrySet()) {
@@ -187,16 +199,13 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements
      * 多线程并发生成试题
      *
      * @param ruleGroups
-     * @param datailMap
      * @return
      */
-    public Map<String, FutureTask<List<Question>>> generateQuestion(List<PaperRuleGroup> ruleGroups, Map<String,
-            List<PaperRuleDetail>> datailMap, List<Question> ruleQuestions) {
+    public Map<String, FutureTask<List<Question>>> generateQuestion(List<PaperRuleGroup> ruleGroups, List<Question> ruleQuestions) {
         Map<String, FutureTask<List<Question>>> resultMap = new LinkedHashMap<>();
         for (PaperRuleGroup g : ruleGroups) {
-            List<PaperRuleDetail> detaiTmps = datailMap.get(g.getId());
             //组内规则明细排序
-            List<PaperRuleDetail> details = detaiTmps.stream().sorted(Comparator.comparing(PaperRuleDetail::getSort)).collect(Collectors.toList());
+            List<PaperRuleDetail> details = g.getRuleList().stream().sorted(Comparator.comparing(PaperRuleDetail::getSort)).collect(Collectors.toList());
             for (PaperRuleDetail d : details) {
                 Callable<List<Question>> genCall = () -> questionService.generateQuestionsByRule(d.getRepositoryId(),
                         g.getQuestionType(), d.getLevel(), d.getNum(), ruleQuestions);
@@ -248,14 +257,14 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements
         if (paper == null) {
             return null;
         }
-        List<PaperRuleGroup> groups = paperRuleGroupService.listByPaperId(paperId);
+        List<PaperRuleGroup> groups = paperRuleGroupService.listGroupAndDetail(paperId);
         PaperDTO paperDTO = new PaperDTO();
         BeanUtils.copyProperties(paper, paperDTO);
         if (!CollectionUtils.isEmpty(groups)) {
             if (paper.getJoinType().intValue() == JoinType.XT.getCode()) {
                 joinTypeOfSelect(paperId, groups);
             } else if (paper.getJoinType().intValue() == JoinType.SJ.getCode()) {
-                joinTypeOfRandom(paperId, groups);
+                joinTypeOfRandom(groups);
             }
         }
         paperDTO.setGroupList(groups);
@@ -292,17 +301,12 @@ public class PaperServiceImpl extends ServiceImpl<PaperMapper, Paper> implements
     /**
      * 随机方式返回
      *
-     * @param paperId
      * @param groups
      */
-    public void joinTypeOfRandom(String paperId, List<PaperRuleGroup> groups) {
-        List<PaperRuleDetail> ruleDetails = paperRuleDetailService.listByPaperId(paperId);
-        Map<String, List<PaperRuleDetail>> datailMap = ruleDetails.stream().collect(Collectors
-                .groupingBy(PaperRuleDetail::getGroupId, Collectors.toList()));
+    public void joinTypeOfRandom(List<PaperRuleGroup> groups) {
         for (PaperRuleGroup g : groups) {
-            List<PaperRuleDetail> temps = datailMap.get(g.getId());
             //组内规则明细排序
-            List<PaperRuleDetail> details = temps.stream().sorted(Comparator.comparing(PaperRuleDetail::getSort)).collect(Collectors.toList());
+            List<PaperRuleDetail> details = g.getRuleList().stream().sorted(Comparator.comparing(PaperRuleDetail::getSort)).collect(Collectors.toList());
             details.stream().forEach(detail -> {
                 detail.setRepositoryName(repositoryService.getById(detail.getRepositoryId()).getTitle());
                 detail.setLevel_dictText(LevelType.getByCode(detail.getLevel()).getValue());

+ 12 - 5
web/src/main/java/com/yntravelsky/buss/exam/paperrulegroup/mapper/PaperRuleGroupMapper.java

@@ -1,17 +1,24 @@
 package com.yntravelsky.buss.exam.paperrulegroup.mapper;
 
-import java.util.List;
-
-import com.yntravelsky.buss.exam.paperrulegroup.entity.PaperRuleGroup;
-import org.apache.ibatis.annotations.Param;
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.yntravelsky.buss.exam.paperrulegroup.entity.PaperRuleGroup;
+
+import java.util.List;
 
 /**
  * @Description: paper_rule_group
  * @Author: jeecg-boot
- * @Date:   2023-02-22
+ * @Date: 2023-02-22
  * @Version: V1.0
  */
 public interface PaperRuleGroupMapper extends BaseMapper<PaperRuleGroup> {
 
+
+    /**
+     * 根据试卷id获取抽题规则组以及规则明细
+     *
+     * @param paperId
+     * @return
+     */
+    List<PaperRuleGroup> listGroupAndDetail(String paperId);
 }

+ 47 - 0
web/src/main/java/com/yntravelsky/buss/exam/paperrulegroup/mapper/xml/PaperRuleGroupMapper.xml

@@ -2,4 +2,51 @@
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="com.yntravelsky.buss.exam.paperrulegroup.mapper.PaperRuleGroupMapper">
 
+    <resultMap id="groupMap" type="com.yntravelsky.buss.exam.paperrulegroup.entity.PaperRuleGroup">
+        <id column="id" property="id" jdbcType="VARCHAR"/>
+        <result column="title" property="title" jdbcType="VARCHAR"/>
+        <result column="paper_id" property="paperId" jdbcType="VARCHAR"/>
+        <result column="question_type" property="questionType" jdbcType="INTEGER"/>
+        <result column="per_score" property="perScore" jdbcType="INTEGER"/>
+        <result column="question_count" property="questionCount" jdbcType="INTEGER"/>
+        <result column="total_score" property="totalScore" jdbcType="INTEGER"/>
+        <result column="sort" property="sort" jdbcType="INTEGER"/>
+
+        <collection property="ruleList" ofType="com.yntravelsky.buss.exam.paperruledetail.entity.PaperRuleDetail">
+            <id column="prd_id" property="id" jdbcType="VARCHAR"/>
+            <result column="repository_id" property="repositoryId" jdbcType="VARCHAR"/>
+            <result column="level" property="level" jdbcType="INTEGER"/>
+            <result column="group_id" property="groupId" jdbcType="VARCHAR"/>
+            <result column="prd_paper_id" property="paperId" jdbcType="VARCHAR"/>
+            <result column="num" property="num" jdbcType="INTEGER"/>
+            <result column="prd_sort" property="sort" jdbcType="INTEGER"/>
+            <result column="prd_question_type" property="questionType" jdbcType="INTEGER"/>
+        </collection>
+    </resultMap>
+    <select id="listGroupAndDetail" resultMap="groupMap">
+        SELECT
+            prg.id,
+            prg.title,
+            prg.paper_id,
+            prg.question_type,
+            prg.per_score,
+            prg.question_count,
+            prg.total_score,
+            prg.sort,
+            prd.id AS prd_id,
+            prd.repository_id,
+            prd.level,
+            prd.group_id,
+            prd.paper_id AS prd_paper_id,
+            prd.num,
+            prd.sort AS prd_sort,
+            prd.question_type AS prd_question_type
+        FROM
+            paper_rule_group prg
+        LEFT JOIN paper_rule_detail prd ON prg.ID = prd.group_id
+        WHERE
+            prg.paper_id =  #{paperId}
+        ORDER BY
+            prg.sort ASC
+    </select>
 </mapper>

+ 8 - 1
web/src/main/java/com/yntravelsky/buss/exam/paperrulegroup/service/IPaperRuleGroupService.java

@@ -3,7 +3,6 @@ package com.yntravelsky.buss.exam.paperrulegroup.service;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.yntravelsky.buss.exam.paper.entity.Paper;
 import com.yntravelsky.buss.exam.paperrulegroup.entity.PaperRuleGroup;
-import com.yntravelsky.buss.exam.questionanswer.entity.QuestionAnswer;
 
 import java.util.List;
 
@@ -30,4 +29,12 @@ public interface IPaperRuleGroupService extends IService<PaperRuleGroup> {
     void remove(String paperId);
 
     void removeByQuestionIds(String[] paperIds);
+
+    /**
+     * 根据试卷id获取抽题规则组以及规则明细
+     *
+     * @param paperId
+     * @return
+     */
+    List<PaperRuleGroup> listGroupAndDetail(String paperId);
 }

+ 14 - 0
web/src/main/java/com/yntravelsky/buss/exam/paperrulegroup/service/impl/PaperRuleGroupServiceImpl.java

@@ -38,6 +38,9 @@ public class PaperRuleGroupServiceImpl extends ServiceImpl<PaperRuleGroupMapper,
     @Autowired
     private IPaperQuestionService paperQuestionService;
 
+    @Autowired
+    private PaperRuleGroupMapper paperRuleGroupMapper;
+
     /**
      * 保存试卷规则组
      */
@@ -135,4 +138,15 @@ public class PaperRuleGroupServiceImpl extends ServiceImpl<PaperRuleGroupMapper,
         wrapper.lambda().in(PaperRuleGroup::getPaperId, paperIds);
         this.remove(wrapper);
     }
+
+    /**
+     * 根据试卷id获取抽题规则组以及规则明细
+     *
+     * @param paperId
+     * @return
+     */
+    @Override
+    public List<PaperRuleGroup> listGroupAndDetail(String paperId) {
+        return paperRuleGroupMapper.listGroupAndDetail(paperId);
+    }
 }