不要在循环中操作数据库(案例)
如何在写业务接口的时候避免在循环中调用接口
·
各位在写代码的时候千万不要在循环中对数据库进行操作,这样会大大降低数据库的性能,今天在写接口的时候碰到了这种情况,被组长说了一下,于是改了改,代码奉上:
@Override
public List<ScrInspectionVo> selectByMcId(String id) {
List<ScrInspectionVo> inspectionVos = this.list(new LambdaQueryWrapper<ScrInspection>()
.eq(ScrInspection::getMcId,id)
.orderByDesc(ScrInspection::getSort))
.stream()
.map(scrInspection -> {
ScrInspectionVo scrInspectionVo = new ScrInspectionVo();
scrInspectionVo.setId(scrInspection.getId());
scrInspectionVo.setMcId(scrInspection.getMcId());
scrInspectionVo.setItemId(scrInspection.getItemId());
scrInspectionVo.setStatus(scrInspection.getStatus());
scrInspectionVo.setCreateTime(scrInspection.getCreateTime());
scrInspectionVo.setSort(scrInspection.getSort());
scrInspectionVo.setType(scrInspection.getType());
scrInspectionVo.setCreateBy(scrInspection.getCreateBy());
//项目筛查数据处理
if (scrInspection.getType().equals(ScreeningConst.PROJECT_SCREENING)){
//根据检查项目id查询检查项目名称
CheckItemTreeVO checkItemTreeVO = remoteKnowledgeApi.selectOne(scrInspection.getItemId(), SecurityConstants.FROM_IN);
scrInspectionVo.setInspectionName(checkItemTreeVO.getClassifyName());
}
//流调筛查数据处理
if (scrInspection.getType().equals(ScreeningConst.EPIDEMIC_SCREENING)){
List<ScrInspectionQuestionVo> scrInspectionQuestionVos = this.selectByQuestionList(ScreeningConst.EPIDEMIC_SCREENING);
scrInspectionQuestionVos.stream().forEach(s->{
scrInspectionVo.setInspectionName(s.getTextName());
});
}
return scrInspectionVo;
}).collect(Collectors.toList());
return inspectionVos;
其中selectByQuestionList和selectOne方法都是调用的其他服务的,全是在循环中调用的接口,这样对于数据库来说的话会有很大压力,所以经过我的整改,写了两个方法,代码奉上:
@Override
@ConverData(serviceId = ServiceNameConstants.KNOWLEDGE_SERVICE, table = "knowledge_check_item", key = "itemId", dbKey = "id", dbValue = "classify_name", value = "inspectionName")
public List<ScrInspectionVo> selectByMcId(String id) {
//根据医联体id查询出医联体下的所有数据
List<ScrInspection> scrInspections = this.list(new LambdaQueryWrapper<ScrInspection>()
.eq(ScrInspection::getMcId, id)
.orderByDesc(ScrInspection::getSort));
//项目筛查
List<ScrInspection> project = scrInspections.stream()
.filter(x -> x.getType()==1).collect(Collectors.toList());
//流调筛查
List<ScrInspection> epidemiological= scrInspections.stream()
.filter(liu -> liu.getType()==0).collect(Collectors.toList());
List<ScrInspectionVo> projectList = initPro(project);
List<ScrInspectionVo> epList = initEp(epidemiological);
List<ScrInspectionVo> vos = new ArrayList<ScrInspectionVo>(projectList);
vos.addAll(epList);
return vos;
}
List<ScrInspectionVo> initPro(List<ScrInspection> pro){
if (CollUtil.isEmpty(pro)){
return new ArrayList<>();
}
return pro.stream().map(p->{
ScrInspectionVo scrInspectionVo = new ScrInspectionVo();
BeanUtils.copyProperties(p,scrInspectionVo);
return scrInspectionVo;
}).collect(Collectors.toList());
}
List<ScrInspectionVo> initEp(List<ScrInspection> epidemiological){
if (CollUtil.isEmpty(epidemiological)){
return new ArrayList<>();
}
//获取到itemId列表
List<String> epIds = epidemiological.stream().map(ScrInspection::getItemId).collect(Collectors.toList());
FormListModel formListModel = new FormListModel();
formListModel.setFormKeys(epIds);
//返回问卷列表
List<FormListVO> epList = remoteMessageApi.getFromList(formListModel, SecurityConstants.FROM_IN).getData();
List<ScrInspectionVo> scrInspectionVos = epidemiological.stream().map(s -> {
ScrInspectionVo scrInspectionVo = new ScrInspectionVo();
BeanUtils.copyProperties(s, scrInspectionVo);
for (FormListVO formListVO : epList) {
if (s.getItemId().equals(formListVO.getFormKey())){
scrInspectionVo.setInspectionName(formListVO.getTextName());
}
}
return scrInspectionVo;
}).collect(Collectors.toList());
return scrInspectionVos;
}
先根据mcId查询出所有数据,然后对这些数据根据条件进行分组,然后自己写两个方法,这样就避免了在循环中重复调用方法,其中initPro和initEp就是我写的两个方法
更多推荐
已为社区贡献1条内容
所有评论(0)