• Redis 好友关注-朋友圈


    使用Redis 中的set类型实现关注功能呢

    关注取关

    1. @Autowired
    2. StringRedisTemplate stringRedisTemplate;
    3. private static final String FOLLOW_KEY_PREFIX = "follow:user:";
    4. /**
    5. * 关注和取关
    6. *
    7. * @param followUserId 关注和取关的userId
    8. * @param isFollow 关注 ,取关 true是关注,false是取关
    9. * @param userId 自己的userId
    10. */
    11. public void follow(Long followUserId, Boolean isFollow, Long userId) {
    12. String key = FOLLOW_KEY_PREFIX + userId;
    13. if (isFollow) {
    14. stringRedisTemplate.opsForSet().add(key, followUserId.toString());
    15. } else {
    16. stringRedisTemplate.opsForSet().remove(key, followUserId.toString());
    17. }
    18. }

    是否关注

    1. /**
    2. * 是否已经关注
    3. *
    4. * @param followUserId 关注和取关的userId
    5. * @param userId 自己的userId
    6. * @return true已关注,false未关注
    7. */
    8. public boolean isFollow(Long followUserId, Long userId) {
    9. String key = FOLLOW_KEY_PREFIX + userId;
    10. Boolean member = stringRedisTemplate.opsForSet().isMember(key, followUserId);
    11. return BooleanUtil.isTrue(member);
    12. }

    共同关注的好友

    1. /**
    2. * 获取共同关注的好友
    3. * @param friendId 好友的id
    4. * @param userId 我的Id
    5. * @return 所有的共同好友
    6. */
    7. public Set commonFollow(Long friendId, Long userId) {
    8. String myKey = FOLLOW_KEY_PREFIX + userId;
    9. String friendKey = FOLLOW_KEY_PREFIX + friendId;
    10. Set intersect = stringRedisTemplate.opsForSet().intersect(myKey, friendKey);
    11. if (CollectionUtil.isEmpty(intersect)){
    12. return null;
    13. }
    14. List ids = intersect.stream().map(Long::valueOf).collect(Collectors.toList());
    15. //模拟数据库根绝userId 集合查询User对象
    16. Set userSet = new HashSet<>();
    17. return userSet;
    18. }

    关注推送

    当被关注的人发朋友圈时,推送给关注的人内容

     

     

     

     

     

      方便起见使用推模式

    1. @Component
    2. public class BlogService {
    3. @Autowired
    4. StringRedisTemplate stringRedisTemplate;
    5. /**
    6. * 保存自己发送的朋友圈, 推送到粉丝的收件箱中
    7. *
    8. * @param blog
    9. */
    10. public void saveBlog(Blog blog) {
    11. //1.模拟保存数据库
    12. //saveBolg(blog);
    13. //2.保存完了将id发送给粉丝
    14. //从数据库查询关系表中followId为 userId的所有userId
    15. //select * from follow where follow_id = ?
    16. List users = new ArrayList<>();
    17. for (Long userId : users) {
    18. String key = "feed:" + userId;
    19. stringRedisTemplate.opsForZSet().add(key, blog.getId().toString(), System.currentTimeMillis());
    20. }
    21. }
    22. /**
    23. * 查看自己收件箱的朋友圈信息,不是一次全部查出来,根绝传入的参数,获取时间戳小于max,跳过offset个后的3条数据
    24. * 这样查询的目的,如果按照角标查询,如果在查询的过程中,又有新的数据插入,则角标变化,导致查询到重复数据,则使用以下方式
    25. * 当第一次查询时max = System.currentTimeMillis(), offset =0的三条记录
    26. * 当第二次时,max = 第一次返回的maxTime, offset 为第一次返回的os记录.
    27. * 这样就可以避免查询到重复的数据
    28. * 在查询过程中,如果想获取最新的第一条数据,则,max = System.currentTimeMillis(), offset =0 就可以查询到最新的朋友圈
    29. * @param max 查询时间戳小于max的记录
    30. * @param offset 在时间戳小于max后跳过几条记录
    31. * @param userId 查询谁的收件箱
    32. * @return ScrollResult
    33. * data为朋友圈详情
    34. * maxTime 查询时间戳的最大值限制
    35. * offset 跳过的个数
    36. */
    37. public ScrollResult getFriendsBlog(Long max, Integer offset, Long userId) {
    38. //查询收件箱
    39. String key = "feed:" + userId;
    40. Set> typedTuples =
    41. stringRedisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, 0, max, offset, 3);
    42. if (CollectionUtil.isEmpty(typedTuples)) {
    43. return null;
    44. }
    45. //解析数据: blogId , minTime(时间戳), offset--跟最小值相同的个数
    46. List ids = new ArrayList<>(typedTuples.size());
    47. long minTime = 0;
    48. int os = 1;
    49. for (ZSetOperations.TypedTuple tuple : typedTuples) {
    50. //获取id
    51. ids.add(Long.valueOf(tuple.getValue()));
    52. //获取分数(时间戳)
    53. long time = tuple.getScore().longValue();
    54. if (minTime == time) {
    55. os++;
    56. } else {
    57. minTime = time;
    58. os = 1;
    59. }
    60. }
    61. //存在一个问题,ids的顺序虽然符合需求的,但是数据库查询时in(...)时,就会乱,则
    62. //sql 改为: select * from Blog where id (5,1) order by FIELD(id , 5,1)
    63. List list = new ArrayList<>();
    64. ScrollResult scrollResult = new ScrollResult(list, minTime, os);
    65. return scrollResult;
    66. }
    67. }
    68. @Data
    69. @AllArgsConstructor
    70. @NoArgsConstructor
    71. class ScrollResult {
    72. List data;
    73. long maxTime;
    74. int offset;
    75. }

  • 相关阅读:
    字符串子序列II
    zabbix 5.0部署
    【前端设计模式】之发布订阅模式
    【数据可视化】—大屏数据可视化展示
    小米手机买什么蓝牙耳机好?适配小米手机的蓝牙耳机推荐
    软交换呼叫中心系统的支撑系统
    sklearn 的 knn 用法
    Kubernetes技术与架构(七)
    Redis安装与生产配置(全网最详细)
    自动驾驶行业观察之2023上海车展-----智驾供应链(3)
  • 原文地址:https://blog.csdn.net/qq_33753147/article/details/126453387