关注的刨析:包括点关注-取消关注-查看共同关注好友

好友关注

1 好友关注-关注和取消关注

针对用户的操作:可以对用户进行关注和取消关注功能。

实现思路:

需求:基于该表数据结构,实现两个接口:

  • 关注和取关接口
  • 判断是否关注的接口

关注是User之间的关系,是博主与粉丝的关系,数据库中有一张follow表来标示。其字段为id -user_id-follow_id=create_time

FollowController

//关注或取消关注
@PutMapping("/{id}/{isFollow}")
public Result follow(@PathVariable("id") Long followUserId, @PathVariable("isFollow") Boolean isFollow) {
    return followService.follow(followUserId, isFollow);
}
//判断是否已经关注
@GetMapping("/or/not/{id}")
public Result isFollow(@PathVariable("id") Long followUserId) {
      return followService.isFollow(followUserId);
}

FollowService

@Override
public Result isFollow(Long followUserId) {
    // 1.获取登录用户
    Long userId = UserHolder.getUser().getId();
    // 2.查询是否关注 select count(*) from tb_follow where user_id = ? and follow_user_id = ?
    Integer count = query().eq("user_id", userId).eq("follow_user_id", followUserId).count();
    // 3.判断
    return Result.ok(count > 0);
}

@Override
public Result follow(Long followUserId, Boolean isFollow) {
    // 1.获取登录用户
    Long userId = UserHolder.getUser().getId();
    // 1.判断到底是关注还是取关
    if (isFollow) {
        // 2.关注,新增数据
        Follow follow = new Follow();
        follow.setUserId(userId);
        follow.setFollowUserId(followUserId);
        boolean isSuccess = save(follow);

    } else {
        // 3.取关,删除 delete from tb_follow where user_id = ? and follow_user_id = ?
        remove(new QueryWrapper<Follow>()
               .eq("user_id", userId).eq("follow_user_id", followUserId));

    }
    return Result.ok();
}

2 好友关注-共同关注

想要去看共同关注的好友,需要首先进入到这个页面,这个页面会发起两个请求

1、去查询用户的详情

2、去查询用户的笔记

以上两个功能和共同关注没有什么关系,大家可以自行将笔记中的代码拷贝到idea中就可以实现这两个功能了,我们的重点在于共同关注功能。

// UserController 根据id查询用户
@GetMapping("/{id}")
public Result queryUserById(@PathVariable("id") Long userId){
  // 查询详情
  User user = userService.getById(userId);
  if (user == null) {
    return Result.ok();
  }
  UserDTO userDTO = BeanUtil.copyProperties(user, UserDTO.class);
  // 返回
  return Result.ok(userDTO);
}

// BlogController  根据id查询博主的探店笔记
@GetMapping("/of/user")
public Result queryBlogByUserId(
    @RequestParam(value = "current", defaultValue = "1") Integer current,
    @RequestParam("id") Long id) {
  // 根据用户查询
  Page<Blog> page = blogService.query()
      .eq("user_id", id).page(new Page<>(current, SystemConstants.MAX_PAGE_SIZE));
  // 获取当前页数据
  List<Blog> records = page.getRecords();
  return Result.ok(records);
}

接下来我们来看看共同关注如何实现:

需求:利用Redis中恰当的数据结构,实现共同关注功能。在博主个人页面展示出当前用户与博主的共同关注呢。

当然是使用我们之前学习过的set集合,在set集合中,有交集并集补集的api,我们可以把两人的关注的人分别放入到一个set集合中,然后再通过api去查看这两个set集合中的交集数据。

我们先来改造当前的关注列表

改造原因是因为我们需要在用户关注了某位用户后,需要将数据放入到set集合中,方便后续进行共同关注,同时当取消关注时,也需要从set集合中进行删除

FollowServiceImpl

@Override
public Result follow(Long followUserId, Boolean isFollow) {
    // 1.获取登录用户
    Long userId = UserHolder.getUser().getId();
    // 1.判断到底是关注还是取关
    String followKey= RedisConstants.FOLLOW_KEY+userId;
    if (isFollow) {
        // 2.关注,新增数据
        Follow follow = new Follow();
        follow.setUserId(userId);
        follow.setFollowUserId(followUserId);
        boolean isSuccess = save(follow);
        //把用户放入到好友列表中redis
        redisTemplate.opsForSet().add(followKey,followUserId);
    } else {
        // 3.取关,删除 delete from tb_follow where user_id = ? and follow_user_id = ?
        remove(new QueryWrapper<Follow>()
               .eq("user_id", userId).eq("follow_user_id", followUserId));
        //把用户从好友列表中移出redis
        redisTemplate.opsForSet().remove(followKey,followUserId);
    }
    return Result.ok();
}

具体的关注代码:

FollowServiceImpl

@Override
public Result followCommon(int id) {
    // 1.获取登录用户
    Long userId = UserHolder.getUser().getId();

    //2.使用redis的set的求交集的命令查看两个集合里面的共同好友
    String myKey = RedisConstants.FOLLOW_KEY+userId;
    String commonKey = RedisConstants.FOLLOW_KEY+id;
    Set<Long> idSet = redisTemplate.opsForSet().intersect(myKey, commonKey);
    if(ObjectUtil.isEmpty(idSet)){
        return Result.ok(Collections.emptyList());
    }
    //3.根据查询出来的用户id生成userDTO。放入Result集合返回。
    List<UserDTO> userDTOs = new ArrayList<>(idSet.size());
    List<User> users = userService.listByIds(idSet);
    if(ObjectUtil.isNotEmpty(users)){
        for(User user : users){
            userDTOs.add(BeanUtil.copyProperties(user,UserDTO.class));
        }
    }
    return Result.ok(userDTOs);
}

附加:当不使用redis中的set还可以用以下方法

		Long loginId = UserHolder.getUserDTO().getId();
		//先根据当前用户的用户id查出关注列表
        List<Follow> follows1 = query().eq("user_id", loginId).list();
        //再根据别的用户的id查出其关注的列表
        List<Follow> follows2 = query().eq("user_id", id).list();
        //取出其关注的共同人的follow_id
        List<String> list1=new ArrayList();
        List<String> list2=new ArrayList();
        for (Follow follow:follows1){
            list1.add(follow.getFollowUserId().toString());
        }
        for (Follow follow:follows2){
            list2.add(follow.getFollowUserId().toString());
        }
        //流式传输求交集
        List<String> collect = list1.stream()
                .filter(list2::contains)
                .collect(Collectors.toList());
        //使用集合的retain求交集
       	list1.retainAll(list2);//这个时间复杂度为O1 stream时间复杂度为On
       	 List<User> users = userService.query().in("id", collect).list();//或list
        List<UserDTO> UserDTOs=new ArrayList<>();
        for (User user:users){
        //使用工具类隐藏user的关键信息
            UserDTOs.add(BeanUtil.copyProperties(user, UserDTO.class));
        }
        return new ressult.ok(UserDTOs);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值