在开发中很多场景下我们都会用到foreach循环遍历一个list,并在内部通过sql再去查询对应的数据,代码如下
public void test(){
// 获取知识点关联数据
List<KnowledgeRelate> list = getKnowledgeRelate();
for(KnowledgeRelate relate : list){
// 执行 list.size() 次sql查询
Knowledge knowledge = knowledgeService.getKnowledge(relate.getKnowledgeId());
if(knowledge != null){
relate.setName(knowledge.getKnowledgeName());
}
}
}
如果是在单机并且数据量不大的情况下可能影响不大,但是在高并发高数据量的情况下如果还是用这种方法处理,就会出现系统奔溃的问题,原因在于多次请求数据库QPS到一定量时,容易导致数据库资源耗尽,可以去后台日志看看就会发现重复执行同个sql语句,这时我们可以用map去匹配处理,查询次数从list.size()降到1,代码如下
public void test(){
// 获取知识点关联数据
List<KnowledgeRelate> relateList = getKnowledgeRelate();
Set<String> knowledgeSet = getKnowledgeInfo();
Map<Long, String> knowledgeMap = Maps.newHashMap();
// 获取知识点信息数据
List<Knowledge> knowledgeList = knowledgeService.listByKnowledgeNames(knowledgeSet);
// 判空处理
if (CollectionUtil.isNotEmpty(knowledgeList)) {
knowledgeMap = knowledgeList.stream()
.collect(Collectors.toMap(Knowledge::getId, Knowledge::getKnowledgeName, (v1, v2) -> v1));
}
// 通过map设值
for(KnowledgeRelate relate : relateList){
relate.setName(knowledgeMap.get(relate.getKnowledgeId()));
}
}