【Redis学习10】好友关注---关注与取关,共同关注及关注推送

本文详细介绍了如何在社交网络应用中实现关注、取关、共同关注以及关注推送的功能。首先,通过AJAX请求处理关注和取关,将用户信息存储在数据库和Redis的Set集合中。接着,实现是否关注的查询功能,根据用户ID和被关注者ID检查数据库记录。共同关注功能通过交集操作从两个用户关注列表中找出共同关注的博主。最后,关注推送部分涉及到Feed流的实现,当用户关注新博主时,将新博客推送给其粉丝。
摘要由CSDN通过智能技术生成

1. 关注与取关

1.1 需求分析

在这里插入图片描述
在这里插入图片描述

1.2 代码实现

首先我们实现关注和取关功能,再实现是否关注功能。

如何实现关注和取关功能呢?我们在页面点击关注按钮,页面会发送ajax请求将要关注或者取关的信息传递到服务端,关注传递的是true,取关传递的是false。同时,页面还将博主的id传递过来。接下来,我们只需要判断是关注还是取关,关注就将当前登录的用户信息保存到follow表,并将用户的信息保存到Set集合中,取关就只需要将Set集合和follow表中的数据删除即可。

为什么要将用户信息放入Set集合呢?因为我们接下去会开发共同关注功能,需要使用,因此提前设置,当然,我这是已经完成全部功能反过来写博客,当初第一次实现也没加入Set集合,后面需要再改也行。

followController.java

	@PutMapping("/{id}/{isFollow}")
    public Result follow(@PathVariable("id") Long followUserId,@PathVariable("isFollow") Boolean isFollow){
        return followService.follow(followUserId,isFollow);
    }

Service

//关注取关操作,followUserId是博主id
    @Override
    public Result follow(Long followUserId, Boolean isFollow) {
        //1. 获取登录用户id
        Long userId = UserHolder.getUser().getId();
        String key = "follows:"+userId;
        //2. 判断是否关注
        if(isFollow){
            //3. 关注,新增
            Follow follow = new Follow();
            follow.setUserId(userId);
            follow.setFollowUserId(followUserId);
            follow.setCreateTime(LocalDateTime.now());
            boolean success = this.save(follow);

            if(success){
                //把用户关注的博主id放入redis的set集合,方便我们做共同关注的业务
                redisTemplate.opsForSet().add(key,followUserId.toString());
            }
            }else {
                //4. 取关,删除 delete from tb_follow where user_id = ? and follow_user_id=?
                boolean success = remove(new QueryWrapper<Follow>().eq("user_id", userId)
                        .eq("follow_user_id", followUserId));
                if(success){
                    redisTemplate.opsForSet().remove(key,followUserId.toString());
                }
        }
        return Result.ok();
    }

在这里插入图片描述

1.3 功能完善

接下来我们完成是否关注功能的开发,业务逻辑很简单,根据当前用户id和博主id查数据库,看看是否有相关数据,有就说明关注,反之则没关注

controller

	@GetMapping("/or/not/{id}")
    public Result isFollow(@PathVariable("id") Long followUserId){
        return followService.isFollow(followUserId);
    }

service

	//是否关注
    @Override
    public Result isFollow(Long followUserId) {
        //1. 获取登录用户id
        Long userId = UserHolder.getUser().getId();
        //查询是否关注 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();
        //大于0就是true
        return Result.ok(count>0);
    }

2. 共同关注

2.1 需求分析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.2 代码实现

分析一波,如何实现共同关注功能呢?还记得我们在实现关注与取关功能中将用户id作为key,将其关注的博主作为值添加到Set集合中嘛,这时,我们就可以将当前登录用户的id作为key查询出其关注的博主,再获取当前用户想查询某个博主的关注列表,两个集合取交集,不就可以查询出共同关注了吗。

如何获取交集呢?在redis基础操作中,我们讲到两个集合取交集是不是有一个intersect方法,调用该方法传递两个key就可以获取出交集。

controller

	@GetMapping("/common/{id}")
    public Result followCommons(@PathVariable("id") Long id){
        return followService.followCommons(id);
    }

sercice

@Override
    public Result followCommons(Long id) {
        //1. 获取当前用户id
        Long userId = UserHolder.getUser().getId();
        String key = "follows:"+userId;
        String key2 = "follows:"+id;
        //2. 求当前用户与查询用户的交集
        Set<String> idSet = redisTemplate.opsForSet().intersect(key, key2);
        //无交集返回空
        if(idSet==null||idSet.isEmpty()){
            return Result.ok(Collections.emptyList());
        }
        //3. 查询出的id为字符串,解析出id
        List<Long> idList = idSet.stream().map(Long::valueOf).collect(Collectors.toList());
        //4. 根据id查询用户,转成dto对象
        List<UserDTO> userDTOS = userService.listByIds(idList)
                .stream()
                .map(user -> BeanUtil.copyProperties(user, UserDTO.class))
                .collect(Collectors.toList());
        //5. 返回dto对象
        return Result.ok(userDTOS);
    }

在这里插入图片描述

3. 关注推送

3.1 关注推送介绍

在这里插入图片描述
在这里插入图片描述

3.2 Feed流的实现方式

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.3 代码实现

在这里插入图片描述

 @Override
    public Result saveBlog(Blog blog) {

        //1. 获取当前用户
        UserDTO user = UserHolder.getUser();
        //2. 新增博客信息
        Long userId = user.getId();
        blog.setUserId(userId);
        boolean success = this.save(blog);
        //3. 添加不成功就不推送
        if(!success){
            return Result.fail("添加博客失败");
        }

        //4 查询博主的所有粉丝
        LambdaQueryWrapper<Follow> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Follow::getFollowUserId,userId);
        List<Follow> followList = followService.list(queryWrapper);
        //5. 添加成功,推送
        //5.1 获取粉丝id
        for (Follow follow : followList) {
            Long userId1 = follow.getId();
            //5.2 推送
            String key = FEED_KEY+ userId1;
            stringRedisTemplate.opsForZSet().add(key,blog.getId().toString(),System.currentTimeMillis());
        }

        //6. 返回博客id
        return Result.ok(blog.getId());
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值