BookRankByRedisServiceImpl.java 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. package com.sf.service.impl;
  2. import com.google.gson.Gson;
  3. import com.sf.cons.RedisKeyConst;
  4. import com.sf.dto.resp.BookRankRespDto;
  5. import com.sf.entity.BookInfo;
  6. import com.sf.mapper.BookInfoMapper;
  7. import com.sf.service.IBookRankService;
  8. import lombok.RequiredArgsConstructor;
  9. import org.springframework.beans.BeanUtils;
  10. import org.springframework.data.redis.core.RedisTemplate;
  11. import org.springframework.data.redis.core.ZSetOperations;
  12. import org.springframework.stereotype.Service;
  13. import java.util.List;
  14. import java.util.Set;
  15. // 基于redis
  16. @Service("bookRankServiceByRedis")
  17. @RequiredArgsConstructor
  18. public class BookRankByRedisServiceImpl implements IBookRankService {
  19. // 数据初始化
  20. private final BookInfoMapper bookInfoMapper;
  21. private final RedisTemplate redisTemplate;
  22. private final Gson gson;
  23. @Override
  24. public List<BookRankRespDto> listVisitRankBooks() {
  25. return getRankDataByRedis(RedisKeyConst.VISIT_ZSET);
  26. }
  27. @Override
  28. public List<BookRankRespDto> listNewestRankBooks() {
  29. return getRankDataByRedis(RedisKeyConst.NEW_ZSET);
  30. }
  31. @Override
  32. public List<BookRankRespDto> listUpdateRankBooks() {
  33. return getRankDataByRedis(RedisKeyConst.UPDATE_ZSET);
  34. }
  35. private List<BookRankRespDto> getRankDataByRedis(String key){
  36. ZSetOperations zSetOperations = redisTemplate.opsForZSet();
  37. Set<String> set = zSetOperations.reverseRange(key, 0, 29);
  38. return set.stream().map(str -> {
  39. // 将map中的每一个元素 转化为BookRankRespDto
  40. BookInfo bookInfo = gson.fromJson(str, BookInfo.class);
  41. BookRankRespDto bookRankRespDto = new BookRankRespDto();
  42. BeanUtils.copyProperties(bookInfo, bookRankRespDto);
  43. return bookRankRespDto;
  44. }).toList();
  45. }
  46. // 数据初始化
  47. // private void initData() {
  48. // List<BookInfo> bookInfos = bookInfoMapper.selectList(null);
  49. // ZSetOperations zSetOperations = redisTemplate.opsForZSet();
  50. // for (BookInfo bookInfo : bookInfos) {
  51. // Long visitCount = bookInfo.getVisitCount();
  52. // String bookInfoJson = gson.toJson(bookInfo);
  53. // zSetOperations.add(RedisKeyConst.VISIT_ZSET, bookInfoJson, visitCount);
  54. // }
  55. // }
  56. // 这是实时榜单的处理逻辑
  57. @Override
  58. public void updateVisitRank(Long bookId) {
  59. BookInfo bookInfo = bookInfoMapper.selectById(bookId);
  60. String json = gson.toJson(bookInfo);
  61. // 此时的问题 是json中包含了访问量参数 而访问量会频繁变化
  62. ZSetOperations zSetOperations = redisTemplate.opsForZSet();
  63. // 每一次更新访问量 就将旧的数据移除 新的数据添加进去 保证数据的统一
  64. zSetOperations.remove(RedisKeyConst.VISIT_ZSET, json);
  65. bookInfo.setVisitCount(bookInfo.getVisitCount() + 1);
  66. zSetOperations.add(RedisKeyConst.VISIT_ZSET, gson.toJson(bookInfo), bookInfo.getVisitCount());
  67. }
  68. }