前言:

我们知道,关注和粉丝已经成为很多信息流平台必备的功能,比如我们的csdn就有这一功能,但是随着关注人的增加,我们如果采用普通数据库的存储可能会满足不了用户的速度上的体验,如:MySQL数据存储是存储在表中,查找数据时要先对表进行全局扫描或者根据索引查找,这涉及到磁盘的查找,磁盘查找如果是按条点查找可能会快点,但是顺序查找就比较慢;而Redis不用这么麻烦,本身就是存储在内存中,会根据数据在内存的位置直接取出。

我的粉丝数太感人了吧,呜呜!~~~~ 

那么Redis它有什么优势呢?

1:读写性能极高 , redis读对的速度是11万次/s , 写的速度是8.1万次/s.

2:redis 支持多种数据类型,redis存储的是 key–value格式的数据,其中key是字符串,但是value就有多种数据类型了:String , list ,map , set ,有序集合(sorted set)

3:非关系性数据库

4:持久化:redis的持久化方式有rdb和 aof 两种,rdb 是将内存中的数据压缩后写入到硬盘上,aof是将日志整理写到硬盘中,而且通过设置可以设置不同的持久化方式,有效的减轻了服务器的压力,同时在很大程度上防止了数据的丢失。

所以我们在涉及到互粉、点赞等数据读写和存储性能要求比高的功能,我们尽量用Redis去解决这些问题!

Redis存放数据的方法:key-value对的形式

这里我们就依据互粉功能来看一下怎么实现Redis的数据存储的吧!

实现功能:

             关注列表  粉丝列表   关注数  粉丝数  关注  取消关注

1.在biuld.gradle引包

 implementation('org.springframework.boot:spring-boot-starter-data-redis')

2.写一个方法类:

RedisHelper 主要用来存放Redis的一些基本方法

public Map<Object, Object> getHash(String key){return mRedisTemplate.opsForHash().entries(key);}
  public void hset(String key, String hashKey, Object value){mRedisTemplate.opsForHash().put(key, hashKey, value);}

关于Resdis的类型用法详戳:Redis的五种数据类型及方法

public void hdel(String key, String...hashKeys) {    //...代表可以有一个参数,也可以有多个参数!mRedisTemplate.opsForHash().delete(key, hashKeys);}
  public Long hLen(String key) {return mRedisTemplate.opsForHash().size(key);}

3.然后我们建立一个 RedisFollowHelper 主要用来存放关注与取消关注的方法实现!

import com.nschool.api.model.User;
import com.nschool.api.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.Map;@Componentpublic class RedisFollowHelper {//爱豆(FOLLOW_USERS) 的粉丝表private static final String FOLLOW_USERS = "USER_%s:myFans";//脑残粉(FANS_USERS) 的关注表private static final String FANS_USERS = "USER_%s:myFollows";@AutowiredRedisHelper redisHelper;@AutowiredUserService mUserService;//userId去关注别人,判断是否已关注public boolean isFollowed(Long followId, User user) {String fanUsersKey = String.format(FANS_USERS, user.getId());Object value = redisHelper.hget(fanUsersKey, String.valueOf(followId));return value != null ;}//followId去关注别人,判断是否已关注public boolean isFollowedByFollowId(Long followId, User user) {String fanUsersKey = String.format(FANS_USERS, followId);Object value = redisHelper.hget(fanUsersKey, String.valueOf(user.getId()));return value != null ;}public void follow(Long followId, User user) {User followUser = mUserService.getUserById(followId);//粉丝的爱豆们String followUsersKey = String.format(FOLLOW_USERS, followId);redisHelper.hset(followUsersKey, String.valueOf(user.getId()), user.getUsername());//爱豆的粉丝们String fanUsersKey = String.format(FANS_USERS, user.getId());redisHelper.hset(fanUsersKey, String.valueOf(followId), followUser.getUsername());}public void unFollow(Long followId, User user) {User followUser = mUserService.getUserById(followId);//粉丝的爱豆们String followUsersKey = String.format(FOLLOW_USERS, followId);redisHelper.hdel(followUsersKey, String.valueOf(user.getId()), user.getUsername());//爱豆的粉丝们String fanUsersKey = String.format(FANS_USERS, user.getId());redisHelper.hdel(fanUsersKey, String.valueOf(followId), followUser.getUsername());}public Map<Object,Object> myFollows(Long userId){String fansUsersKey = String.format(FANS_USERS,userId);Map<Object,Object> objectMap = redisHelper.getHash(fansUsersKey);return objectMap;}public Map<Object,Object> myFans(Long followId){String followUsersKey = String.format(FOLLOW_USERS, followId);Map<Object,Object> objectMap = redisHelper.getHash(followUsersKey);return objectMap;}public Long  myFollowCount(Long userId){String fansCountKey = String.format(FANS_USERS, userId);Long fansCount= redisHelper.hLen(fansCountKey);return  fansCount;}public Long myFansCount(Long followId){String followCountKey = String.format(FOLLOW_USERS, followId);Long followCount= redisHelper.hLen(followCountKey);return  followCount;}
}

4.创建userService类  对关注接口的业务逻辑进行进一步的设计

@Service
public class UserService extends BaseService {/**** @param followId 关注人的ID* @param user  去关注人的ID*/@Transactionalpublic boolean isFollowed(Long followId, User user) {return redisFollowHelper.isFollowed(followId, user);}@Transactionalpublic void follow(Long followId, User user) {redisFollowHelper.follow(followId, user);}@Transactionalpublic void unFollow(Long followId, User user) {redisFollowHelper.unFollow(followId, user);}@Transactionalpublic  List<FollowUserResp> myFollows(){Long userId=getCurrentUserId();return getFriendList(userId,redisFollowHelper.myFollows(userId));}@Transactionalpublic List<FollowUserResp> myFans(){Long followId=getCurrentUserId();return getFriendList(followId,redisFollowHelper.myFans(followId));}private boolean isFollowedByFollowId(Long followId, User user) {return redisFollowHelper.isFollowedByFollowId(followId, user);}@Transactionalpublic  Long  myFollowCount(Long targetUserId){targetUserId=getTargetCount(targetUserId);Long count = redisFollowHelper.myFollowCount(targetUserId);return  count;}@Transactionalpublic  Long myFansCount(Long targetUserId){targetUserId=getTargetCount(targetUserId);Long count = redisFollowHelper.myFansCount(targetUserId);return  count;}/*** 获得用户关注或者粉丝列表* @param currUserId 当前用户* @param objectMap  调用方法* @return*/private  List<FollowUserResp> getFriendList(Long currUserId, Map<Object,Object> objectMap){List<FollowUserResp> followUserRespList = new ArrayList<>();for (Map.Entry<Object, Object> entity :objectMap.entrySet()) {Object key = entity.getKey();Long id = Long.valueOf(String.valueOf(key));User user = getUserById(id);FollowUserResp followUserResp = new FollowUserResp();followUserResp.setId(user.getId());followUserResp.setUsername(user.getUsername());followUserResp.setAvatar(user.getAvatar());followUserResp.setGender(user.getGender());if (isFollowedByFollowId(currUserId, user)) {followUserResp.setFollowed(true);} else{followUserResp.setFollowed(false);}followUserRespList.add(followUserResp);}return followUserRespList;}}

5.创建userController类,作为接口调用类

@RestController
@RequestMapping("user")
@Api(value = "用户接口", tags = {"用户接口"})
public class UserController extends BaseController {@AutowiredUserService mUserService;@ApiOperation(value = "关注", notes = "关注")@PostMapping("follow")public Result follow(@RequestParam Long followId){User user = getCurrentUser();if (mUserService.isFollowed(followId, user)) {return Result.success( "您已经关注!");}mUserService.follow(followId, user);return Result.success( "感谢亲的关注!");}@ApiOperation(value = "取消关注", notes = "取消关注")@PostMapping("unFollow")public Result unFollow(@RequestParam Long followId){User user = getCurrentUser();if (!mUserService.isFollowed(followId, user)) {return Result.success( "您已经取消关注!");}mUserService.unFollow(followId, user);return Result.success("取消关注") ;}@ApiOperation(value = "加载关注列表",notes = "加载关注列表")@GetMapping("myFollow")public Result<List<FollowUserResp>> myFollows(){List<FollowUserResp> followUserResp = mUserService.myFollows();return Result.success(followUserResp);}@ApiOperation(value = "加载粉丝列表",notes = "加载粉丝列表")@GetMapping("myFans")public Result<List<FollowUserResp>> myFans(){List<FollowUserResp> followUserResp = mUserService.myFans();return Result.success(followUserResp);}@ApiOperation(value = "获取关注数",notes = "获取关注数")@GetMapping("myFollowCount")public Result<Long> myFollowCount(@RequestParam (value = "targetUserId",required = false)Long targetUserId){Long count = mUserService.myFollowCount(targetUserId);return Result.success(count);}@ApiOperation(value = "获取粉丝数",notes = "获取粉丝数")@GetMapping("myFansCount")public Result<Long> myFansCount(@RequestParam (value = "targetUserId",required = false)Long targetUserId){Long count = mUserService.myFansCount(targetUserId);return Result.success(count);}
}    

Redis的应用实例:关注和粉丝的 实现相关推荐

  1. Redis数据结构Set应用场景--黑名单校验器、京东与支付宝抽奖、微博榜单与QQ群的随机展示、帖子点赞、关注与粉丝、微关系计算、HyperLogLog的入门使用

    Set应用场景 set命令使用 淘宝黑名单 一.黑名单过滤器业务场景分析 二 .解决的技术方案 三.SpringBoot+redis模仿实现校验器 京东京豆抽奖 一.京东京豆抽奖的业务场景分析 二.京 ...

  2. 【Redis的应用-关注和粉丝】

    Redis的应用实例:关注和粉丝的 实现 前言: 我们知道,关注和粉丝已经成为很多信息流平台必备的功能,比如我们的csdn就有这一功能,但是随着关注人的增加,我们如果采用普通数据库的存储可能会满足不了 ...

  3. 基于Redis的微博关注与粉丝

    基于Redis的微博关注与粉丝 一.微博关注与粉丝的业务场景分析 阿甘关注了雷军:阿甘就是雷军的粉丝follower 雷军被阿甘关注:雷军就是阿甘的关注followee 二.微博关注与粉丝的redis ...

  4. Redis社交应用里面之关注、粉丝、共同好友案例

    一 背景 社交应用里面的知识,关注.粉丝.共同好友案例 二 代码 public void testSet(){ ​BoundSetOperations operationLW = redisTempl ...

  5. 4.3 关注、取消关注和关注、粉丝列表

    文章目录 设计Redis的key和Value 开发关注.取关的业务 开发Controller,接受关注取关请求 修改主页的js 增加获取关注,粉丝数量,是否关注的业务 主页的Controller 修改 ...

  6. php版redis插件,SSDB数据库,增强型的Redis管理api实例

    php版redis插件,SSDB数据库,增强型的Redis管理api实例 SSDB是一套基于LevelDB存储引擎的非关系型数据库(NOSQL),可用于取代Redis,更适合海量数据的存储. 另外,r ...

  7. 关注与粉丝表结构设计及查询

    概述 关注与粉丝表一般包含我关注的用户,可以查询到我的粉丝列表,查询我关注的用户他们关注了哪些用户等这些功能. 表结构设计 字段  说明 id 主键 user_id 用户ID focus_user_i ...

  8. python爬取微博用户关注和粉丝的公开基本信息

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:TM0831 PS:如有需要Python学习资料的小伙伴可以加点击下 ...

  9. 如何在公众号被关注后回复文本,链接,图文,图片, 已关注的粉丝扫码后, 也会自动回复

    如何在公众号被关注后回复文本,链接,图文,图片, 已关注的粉丝扫码后, 也会自动回复 一.实现原理 二.操作方法 三.产品功能介绍 ) 一.实现原理 微信公众平台具备[参数二维码]功能,利用微星极光- ...

最新文章

  1. 12.流水线设计方式
  2. 对深拷贝与浅拷贝的再次理解
  3. UINavigationController
  4. 简述与oracle相关的程序组,北语网院18秋《Oracle数据库开发》作业_4答案
  5. python注册登陆程序未响应_SpringBoot实现登录注册常见问题解决方案
  6. UP及按照UP进行软件开发的流程
  7. 最大子段和动态规划_动态规划解决最大正方形问题
  8. layer 父弹出框上弹出子弹框窗体大小问题
  9. Linux内核分析——操作系统是如何工作的
  10. 【我评】——关于《中國化風格的淺析》
  11. oppo android版本升级失败,oppo怎么刷机以及刷机失败的原因
  12. minmax()函数
  13. 2020 1月 月末总结
  14. Ubuntu Samba高危安全漏洞修复
  15. (蓝桥杯)数字三角形。。(最简单的dp题)
  16. SQL面试题练习记录
  17. 为什么进入boot怎么只有计算机这个应用,电脑开机就进入bios的解决方法
  18. 上海众生无耻的IDC
  19. The Indian Job
  20. Field userMapper in baizhi.service.impl.UserServiceImpl required a bean of type ‘baizhi.mapper.UserM

热门文章

  1. Svg颜色渐变和阴影
  2. 巴厘岛不如传说中美丽
  3. 2月11绝地求生服务器维护,绝地求生11月27日维护公告 11月27日维护内容
  4. sketch设计android,安卓手机预览sketch设计稿的偏方
  5. 华为鸿蒙审核几天,鸿蒙审核需要多久?
  6. 链表删除指定元素算法
  7. 【codeforces 709D】Recover the String
  8. c语言编译运行程序,用visual c++ 运行C语言程序的过程
  9. 学生党开学季数码好物有哪些值得分享,分享实用性不错的数码好物
  10. tan函数在线性方程中的美妙应用