代码优化的案例

开发过程中,常常会出现for循环里面,存在多个SQL查询,根据for循环里面某个字段或者某2个字段去查询数据库,然后拿到结果,这个过程,如果for循环的集合比较大,同时如果查询的数据库的表有连表或者数据量较大,那么整个查询效率就会很低,我们可以将其进行优化,提高查询效率,话不多说直接上代码

原代码:

  for(Order order : orderList) {
            ReportViewResp resp = new ReportViewResp();
            BeanUtils.copyProperties(order, resp);
            createReportInfo(infoType,resp, order);
            result.add(resp);
        }
private void createReportInfo(InfoType infoType,ReportViewResp resp, Order order) {
     Lab lab = labCommand.getById(order.getLabId());if (Objects.nonNull(lab)) {
            resp.setLab(lab.getLabName());
        }
        Sample sample = sampleCommand.getById(order.getSampleId());if (Objects.nonNull(sample)) {
            resp.setSample(sample.getSampleName());
        }
     ...
}

如上图所示,createReportInfo方法里面有多个查询数据库的操作,这里是省略了,其实是有8个查询数据库,那我们都知道每次和数据库交互都会有连接,其实效率是比较低的,那鉴于此,我们将其尝试优化下

优化后:

        InfoType infoType = handleDataMap(orderList);
        for(Order order : orderList) {
            ReportViewResp resp = new ReportViewResp();
            BeanUtils.copyProperties(order, resp);
            createReportInfo(infoType,resp, order);
            result.add(resp);
        }
private InfoType handleDataMap(List<Order> orderList) {
        InfoType infoType = new InfoType();
        // TestType testType = testTypeCommand.getById(order.getTestTypeId());
        List<Long> testTypeIds = orderList.stream().map(Order::getTestTypeId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<TestType> testTypeList = testTypeCommand.list(new LambdaQueryWrapper<TestType>().in(TestType::getId, testTypeIds));
        Map<Long, TestType> testTypeMap = testTypeList.stream().collect(Collectors.toMap(TestType::getId, TestType -> TestType));
        infoType.setTestTypeMap(testTypeMap);
        // Lab lab = labCommand.getById(order.getLabId());
        List<Long> labIds = orderList.stream().map(Order::getLabId).filter(Objects::nonNull).distinct().collect(Collectors.toList());
        List<Lab> labList = labCommand.list(new LambdaQueryWrapper<Lab>().in(Lab::getId, labIds));
        Map<Long, Lab> labMap = labList.stream().collect(Collectors.toMap(Lab::getId, Lab -> Lab));
        infoType.setLabMap(labMap);
}
@Data
public class InfoType {

    private Map<Long, TestType> testTypeMap = new HashMap<>();

    private Map<Long, Lab> labMap = new HashMap<>();

}
    private void createReportInfo(InfoType infoType,ReportViewResp resp, Order order) {
        Map<Long, Lab> labMap = infoType.getLabMap();
        Lab lab = labMap.get(order.getLabId());
        if (Objects.nonNull(lab)) {
            resp.setLab(lab.getLabName());
        }
        Map<Long, Sample> sampleMap = infoType.getSampleMap();
        Sample sample = sampleMap.get(order.getSampleId());
        if (Objects.nonNull(sample)) {
            resp.setSample(sample.getSampleName());
        }

}

大致的思路就是先把结果集去查询数据库,然后转换为map或者list,再在下游拿到map,通过map.get(xx)的方式去获取到对应的数据,减少了for循环里面遍历查询数据。这里创建个对象是为了方便传递参数,如果只有1-2个,也可以直接传递map,如果存在多个,可以用创建个对象赋值属性的方式来使用。

下面再保存几个类似的案例:

@Data
public class DfmeaInfoByType {
    private Map<Long, List<DfmeaTree>> treeMapByTreeId = new HashMap<>();

    private Map<Long, FmeaKFa> fmeaKFaMap = new HashMap<>();

    private Map<Long, DfmeaTree> dmfeaTreeByRelateFailIdsMap = new HashMap<>();
private List<FmeaStructuralTreeRules> fmeaStructuralTreeRulesList = new ArrayList<>();

 

 treeMapByTreeId

           #上游创建
LambdaQueryWrapper<DfmeaTree> treeLambdaQueryWrapper = new LambdaQueryWrapper<>(); treeLambdaQueryWrapper.in(!treeIds.isEmpty(),DfmeaTree::getAboutProdId, treeIds).or().apply(treeIds.isEmpty(),"1=0"); ; List<DfmeaTree> dfmeaTrees = this.baseMapper.selectList(treeLambdaQueryWrapper); Map<Long, List<DfmeaTree>> treeMapByTreeId = dfmeaTrees.stream().collect(Collectors.groupingBy(DfmeaTree::getAboutProdId)); infoByType.setTreeMapByTreeId(treeMapByTreeId);

      #下游使用 

         Map<Long, List<DfmeaTree>> treeMapByTreeIdMap = infoMap.getTreeMapByTreeId();
        List<DfmeaTree> dfmeaTrees = treeMapByTreeIdMap.getOrDefault(obj.getTreeId(),Collections.emptyList());
        if(dfmeaTrees.size() > 0) {
          treeNode.putExtra("hasChild", 1);
        } else {
          treeNode.putExtra("hasChild", 0);
        }

 

 fmeaKFaMap 

       #上游创建
        LambdaQueryWrapper<FmeaKFa> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(FmeaKFa::getId,knowledgeIds).select(FmeaKFa::getId,FmeaKFa::getInvalidType);
        List<FmeaKFa> fmeaKFaList = this.fmeaKFaService.list(wrapper);
        Map<Long, FmeaKFa> fmeaKFaMap = fmeaKFaList.stream().collect(Collectors.toMap(FmeaKFa::getId, FmeaKFa -> FmeaKFa, (v1, v2) -> v1)); ##这里(v1, v2) -> v1),意思是如果存在多个,取第一个,而如果你确定只有一个,那不需要写这个

infoByType.setFmeaKFaMap(fmeaKFaMap);
        
#下游使用
Map
<Long, FmeaKFa> fmeaKFaMap = infoMap.getFmeaKFaMap();
FmeaKFa fmeaKFa
= fmeaKFaMap.get(obj.getKnowledgeId());
treeNode.putExtra(
"invalidType", fmeaKFa.getInvalidType());
treeNode.putExtra(
"text", fmeaTreeData.getDescName());

 

 dmfeaTreeByRelateFailIdsMap 

          #上游创建      
          Set<Long> relateFailIds = fmeaTreeDataList.stream().map(FmeaTreeData::getRelateFailId).filter(ObjectUtil::isNotNull).collect(Collectors.toSet());  #这里可以将结果集去null去重
                LambdaQueryWrapper<DfmeaTree> wrapper = new LambdaQueryWrapper<DfmeaTree>()
                        .in(!relateFailIds.isEmpty(),DfmeaTree::getId, relateFailIds).or().apply(relateFailIds.isEmpty(),"1=0");     ##这一行代码的意思是,当relateFailIds不为空的时候,就用relateFailIds,当如果relateFailIds为空的时候,1=0为恒假条件,查询结果为空,就返回一个空的集合
                wrapper.select(DfmeaTree::getId,DfmeaTree::getAboutProdId,DfmeaTree::getKnowledgeId);
                List<DfmeaTree> dfmeaTreeList = this.list(wrapper);
                Map<Long, DfmeaTree> dmfeaTreeByRelateFailIdsMap = dfmeaTreeList.stream().collect(Collectors.toMap(DfmeaTree::getId, DfmeaTree -> DfmeaTree));  ##这里因为通过id查询,有把握对象就只有一个,就不要v1、v2了,直接就写成这样
                infoByType.setDmfeaTreeByRelateFailIdsMap(dmfeaTreeByRelateFailIdsMap);
       #下游使用
               Map<Long, DfmeaTree> dmfeaTreeByRelateFailIdsMap = infoMap.getDmfeaTreeByRelateFailIdsMap();
            DfmeaTree dfmeaTree = dmfeaTreeByRelateFailIdsMap.get(relateFailId);

 

 fmeaStructuralTreeRulesList 

         #上游创建
  List<FmeaStructuralTreeRules> fmeaStructuralTreeRulesList = rulesService.list(
                    new LambdaQueryWrapper<FmeaStructuralTreeRules>().select(FmeaStructuralTreeRules::getId));
            infoByType.setFmeaStructuralTreeRulesList(fmeaStructuralTreeRulesList);

         #下游使用
          //List<FmeaStructuralTreeRules> list = rulesService.list();
        List<FmeaStructuralTreeRules> list = infoMap.getFmeaStructuralTreeRulesList();
        if (CollUtil.isNotEmpty(list)) {
            d = String.valueOf(list.get(0).getDfmeaD());
        }

 

 

 

 

 

 

 

 

 

posted @ 2026-02-06 15:47  多多指教~  阅读(18)  评论(0)    收藏  举报