仿牛客社区项目笔记-点赞关注模块(引入Redis)
1. 点赞关注模块
分为Redis,点赞,收到的赞,关注和粉丝。
1.1 Redis
- 安装Redis。并且在pom.xml中加入 spring-boot-starter-data-redis 起步依赖。在 application.properties 上配置Redis。
- 在 config 中配置 RedisConfig 类,返回 RedisTemplate 类。该类可以对 Redis 数据库进行操作。
- Redis中的key值都在 RedisKeyUtil 中定义。
1.2 点赞
前提:在 util 的 RedisKeyUtil 工具类中写 getEntityLikeKey 方法,传入 entityType, entityId 返回某个实体(帖子或回复)的赞的key值 。
分为两种:① 给帖子点赞 ② 给回复点赞。
- ① 在帖子详情页面对帖子内容点赞,按钮通过 discuss.js 将 entityType=0 , 帖子id:entityId 和 entityUserId 通过 /like 映射传递给 LikeController 层中的 like 方法。
- like 方法通过调用 likeService 层的 like 进行点赞功能,然后再依次调用 findEntityLikeCount,findEntityLikeStatus 方法查询该帖子的点赞数量,查询当前登录用户的点赞状态。
- likeService 层的 like 方法首先判断是否已经点过赞了,如果没有,就在Redis中该帖子key对应的set中加入点赞者的userId,并且对该帖子用户的赞的总数加一。如果已经赞过则移除UserId,并且对该帖子用户的赞的总数减一。(此处使用了事务,因为需要同时进行两个业务)
- 触发 Topic 为 TOPIC_LIKE 的事件: 构建Event,设置当前登录用户id,被点赞对象的type,被点赞对象的id,被点赞对象所在的帖子id(因为被点赞的对象可能是帖子或者回复),被点赞对象的用户id。然后调用 eventProducer 将 Event 发布到指定 Topic。
- 将点赞的数量和状态装入map,通过json字符串返回。在浏览器中显示。
- ② 在帖子详情页面对回复点赞,按钮通过 discuss.js 将 entityType=1 和 回复id:entityId 和 entityUserId 通过 /like 映射传递给 LikeController 层中的 like 方法。
注: 另外在 HomeController 层中 /index 映射的方法中,增加向浏览器返回帖子赞的数量的功能。在 DiscussPostController 层中 /detail/{discussPostId} 映射的方法中,增加向浏览器返回帖子和回复列表的赞数量和状态的功能。
1.3 收到的赞
前提:在 util 的 RedisKeyUtil 工具类中写 getUserLikeKey 方法,返回某个用户的赞总数的key。
- 点击个人主页或者点击其他用户头像进入他人个人主页,映射到 UserController层(/user)的 /profile/{userId} 。首先判断该用户存不存在。
- 然后根据该用户的 id 调用 likeService.findUserLikeCount 方法返回点赞数量。findUserLikeCount 方法首先根据userId 调用 getUserLikeKey 方法,返回该用户的赞总数的key。然后使用 redisTemplate 查询key对应的值返回给点赞数量。
- 将点赞数量加入model中返回浏览器显示。
1.4 关注和粉丝
前提:在 util 的 RedisKeyUtil 工具类中写 getFolloweeKey 和 getFollowerKey 方法,返回某个用户关注的实体的key和某个实体拥有的粉丝的key。
1.4.1 点击关注按钮
- 在他人个人主页点击关注,根据 profile.js 异步请求映射到 FollowController 层的 /follow。传入entityType 和 entityId。然后调用 followService.follow 方法进行关注。
- followService.follow 方法首先根据 userId, entityType, entityId 获取到前提中的两个key,开启事务,对当前登录用户的关注的key对应的 ZSet 加入 entityId。被关注用户的粉丝的key对应的 ZSet 加入 userId(Redis存的是有序Set,score采用当前时间插入)。
- 触发 Topic 为 TOPIC_FOLLOW 的事件: 构建Event,设置当前登录用户id,被关注对象的type,被关注对象的id,被关注对象的用户id(与被关注对象的id相同)。然后调用 eventProducer 将 Event 发布到指定 Topic。
- 返回关注成功Json。
- 此时按钮显示已关注,若再次点击则映射到 /unfollow。调用 followService.unfollow 方法取消关注。与第2步骤逻辑基本相同,分别减一。
1.4.2 显示关注和粉丝数量
- 在个人主页显示关注和粉丝的个数,与 1.3 相同,点击个人主页或者点击其他用户头像进入他人个人主页,映射到 UserController层(/user)的 /profile/{userId} 。首先判断该用户存不存在。
- 根据 followService 层的 findFolloweeCount 和 findFollowerCount 方法查询该用户的关注数量和粉丝数量。同时通过 hasFollowed 方法查询当前登录用户是否已经关注该用户。
- 将各个参数加入model,返回给 /site/profile。
1.4.3 显示关注和粉丝列表
- 在个人主页点击关注xx人,映射到 FollowController 层的 /followees/{userId}。首先根据 userId判断该用户是否存在。然后设置分页信息。通过 followService.findFollowees 方法返回该用户的关注列表。
- findFollowees 方法根据 userId 查询关注者id列表。根据id列表生成一个map列表。map列表中装入id对应的User和关注时间。返回给Controller。
- Controller接收到列表,然后再判断一下当前登录用户对该列表中的用户是否已经关注,将该字段放入map列表中。返回给 /site/followee 显示。
- 点击粉丝xx人,映射到 /followers/{userId}。逻辑与上面基本一致,就是查询的key不同。返回给 /site/follower显示。