背景:

用户表: userId、username

帖子表: id、userId、content

需要给前端返回一个帖子VO列表List<ResultVO>,VO中的字段有,帖子的内容content、和用户的信息对象User

一般思路

先查询帖子表,然后for循环遍历帖子表,根据每个VO对象中的userId,再去查询User表,然后把User对象拼接到VO对象中

 //创建结果对象
 List<ResultVO> result=new ArrayList<>();
 //获取帖子
 List<TZ> tzList=tzService.seletAll();
 ​
 //遍历帖子,把帖子加入到结果对象, 并插入用户对象
 for(TZ tz:tzList){
 ​
     ResultVO resultVo=new ResultVO();
     resultVO.setTZ=tz;
     
     Integer userId=tz.getUserId();
     User user=userService.selectById(userId);
     
     resultVO.setUser(user);
     
     reuslt.add(resultVO);
 }
 ​
 return result;

缺点

查询帖子:1次

查询用户:n次(一个帖子就要查一个用户)

查询次数过多,性能过慢,而且一个用户可能有多个帖子,一条用户数据可能被查询多次,不合理。

由于查询次数过多,会消耗连接池中的链接,并且查询数据库也是需要网络连接流量的

优化后的思路

简述:一次性查出帖子,然后把帖子中的userId提取出来作为一个userId列表,最后在根据这个userId列表一次性把userId对应的用户查出来作为一个User列表,最后根据userId把帖子列表和User列表拼接起来,这样就能做到只用查询数据库2次

详细描述:

先查询帖子表,拿到帖子对象列表List<TZ> tzList; ——查询数据库1次

然后在帖子对象列表中,提取用户id集合 Set<Long> userIdList;

然后根据用户id集合userIdList查询数据库,得到用户列表后对用户列表进行分组,得到一个id和用户对象User的映射Map<Long,List<User>> userIdListMap

——查询数据1次

这里其实也可以使用的是Map<Long,User>的结构,这里使用Map<User,List<User>> 是为了防止数据库中有数据错误,导致一个id有多个用户

分组的目的也是为了简化代码开发,如果不分组的话,要有两层for循环,遍历帖子列表后,再遍历用户列表,把对应的用户拼接上。

而分组后,把用户id作为key,可以直接使用containsKey()方法,快速早到用户对象,时间为O(1)

最后遍历把对应的用户信息拼接上去即可

 //创建结果对象
 List<ResultVO> result=new ArrayList<>();
 //获取帖子
 List<TZ> tzList=tzService.seletAll();
 ​
 //获取用户id集合
 Set<Long> userIdList=tzList.stream().map(TZ::getUserId).collect(Colletions.toSet());
 //获取用户集合
 List<User> userList=userService.selectByIds(userIdList);
 //根据id分组
 Map<Long, List<User>> userIdUserListMap =userList.stream().collect(Collectors.groupingBy(User::getId));
 ​
 //拼接信息
 result=tzList.stream().map(tz->{
     ResultVO resultVO=new ResultVO();
     Long userId=tz.getUserId();
     User user=null;
     if(userIdUserListMap.containsKey(userId)){
         user = userIdUserListMap.get(userId).get(0);
     }
     resultVO.setUserVO(user);
     return resultVO;
 }).collect(Collectors.toList());
 ​
 /*
 **不分组的写法
 for(TZ tz:tzList){
 ​
     ResultVO resultVo=new ResultVO();
     resultVO.setTZ=tz;
     
     //对比用户id,进行拼接
     Integer userId=tz.getUserId();
     for(User user:UserList){
         if(user.getId()==userId){
         resultVO.setUser(user);
         }else{
             resultVO.setUser(null);
         }
     }
     
     reuslt.add(resultVO);
 }
 */
 return result;


文章作者: 落叶知秋
本文链接:
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 落叶知秋
喜欢就支持一下吧