用户关注功能

用户关注功能 介绍本文将介绍如何通过redismysql数据库实现用户关注以及查看共同关注的功能。、前置准备创建一个tb_follow表用于记录关注信息。以及一个redis数据库。实现思路主要实现3个接口isFollow接口进入up主页时调用判断用户是否关注了当前up主如果已经关注返回true否则返回false。follow接口点击关注按钮时调用如果已经关注了该up则取关反之关注up。followCommons接口点击共同关注按钮时调用查看你和up都关注了哪些用户。isFollowcontroller接收请求参数idup主id调用service中的业务逻辑。GetMapping(/or/not/{id})publicResultisFollow(PathVariableLongid){returnfollowService.isFollow(id);}serviceOverridepublicResultisFollow(Longid){LonguserIdUserHolder.getUser().getId();longcountquery().eq(user_id,userId).eq(follow_user_id,id).count();returnResult.ok(count0);}业务逻辑从上下文threadlocal中获取当前用户id根据用户id和up主id在tb_follow中查询数据返回数据count 0如果有数据则为true否则为false。followcontroller接收请求参数idup主idisFollowtrue代表执行关注false代表执行取关调用service中的业务逻辑。PutMapping({id}/{isFollow})publicResultfollow(PathVariableLongid,PathVariableBooleanisFollow){returnfollowService.follow(id,isFollow);}serviceOverridepublicResultfollow(Longid,BooleanisFollow){LonguserIdUserHolder.getUser().getId();//判断当前用户是否关注Stringkeyfollow:userId;if(isFollow){//关注新增数据FollowfollownewFollow();follow.setUserId(userId);follow.setFollowUserId(id);booleanisSuccesssave(follow);if(isSuccess){//把关注用户的id放入redis的set集合中keyfollow:userId valuefollowUserIdstringRedisTemplate.opsForSet().add(key,id.toString());}}else{//取关删除数据booleanisSuccessupdate().eq(user_id,userId).eq(follow_user_id,id).remove();if(isSuccess){//把关注用户的id从redis的set集合中移除stringRedisTemplate.opsForSet().remove(key,id.toString());}}returnResult.ok();}业务逻辑从上下文threadlocal中获取当前用户id。执行关注或取关关注将信息写入follow实体属性与tb_follow表字段一致并写入数据库如果操作成功再放入redis的set集合中。取关删除数据库信息如果成功再移除redis的set集合中的id。followCommonscontroller接收请求参数id当前查看up主的id。GetMapping(/common/{id})publicResultfollowCommons(PathVariableLongid){returnfollowService.followCommons(id);}serviceOverridepublicResultfollowCommons(Longid){LonguserIdUserHolder.getUser().getId();StringmyKeyfollow:userId;StringtargetKeyfollow:id;//求交集SetStringintersectstringRedisTemplate.opsForSet().intersect(myKey,targetKey);if(intersectnull||intersect.isEmpty()){//没有共同关注returnResult.ok(没有共同关注);}//解析id集合ListLongcommonIdsintersect.stream().map(Long::valueOf).collect(Collectors.toList());//查询用户ListUserusersuserService.listByIds(commonIds);//转换为DTOListUserDTOuserDTOSusers.stream().map(user-BeanUtil.copyProperties(user,UserDTO.class)).collect(Collectors.toList());returnResult.ok(userDTOS);}业务逻辑获取两者在redis中的key。求两者交集。交集为空-直接返回结果有交集-解析出id集合根据id集合查询用户返回数据。核心要点关注时将id放入redis中的set集合优点查询效率Redis Set 的SINTER命令可以一次求出交集时间复杂度 O(min(n,m))非常高效去重Set 自动去重保证关注列表不重复内存优化相比数据库查询Redis 内存操作快几十倍