『博客开发日记』之修复 首次启动时无法从 redis 中获取 viewCount 的 bug

本文最后更新于 2026年6月15日 下午

修复 首次启动时无法从 redis 中获取 viewCount 的 bug


前言

在初期开发中没有考虑到部署时 redis 中的 viewCount 是没有的

这就导致首次启动时无法从 redis 中获取 viewCount 而报错

然后文章什么都看不了

这次对文章阅读量这个板块做针对性修复


代码实现

在读取 redis 中的 viewCount 时发现没有 viewCount 就从数据库中读取再写入 redis

在 ArticleServiceImpl 中新加一个方法 用于解决这个问题

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//获取文章浏览量,优先读 Redis,若 Redis 中不存在则回源数据库并写入 Redis。
private Long getViewCountWithFallback(Long articleId)
{
//先读 Redis
Integer viewCount = redisCache.getCacheMapValue(RedisKeyConstants.ARTICLE_VIEW_COUNT_KEY, articleId.toString());
if (viewCount != null) {
return viewCount.longValue();
}

//若 Redis 中不存在则回源数据库并回写 Redis
Article article = getById(articleId);
Long dbViewCount = article != null && article.getViewCount() != null ? article.getViewCount() : 0L;
redisCache.setCacheMapValue(RedisKeyConstants.ARTICLE_VIEW_COUNT_KEY, articleId.toString(), dbViewCount.intValue());
return dbViewCount;
}

ArticleServiceImpl 中的 articleList 和 getArticleDetail 方法添加上使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
//分页查询文章列表
@Override
public ResponseResult articleList(Integer pageNum, Integer pageSize)
{
//查询条件
LambdaQueryWrapper<Article> lambdaQueryWrapper = new LambdaQueryWrapper<>();
//只查询分类状态正常的文章(使用子查询)
lambdaQueryWrapper.inSql(Article::getCategoryId,
"SELECT id FROM category WHERE status = '0' AND del_flag = '0'");
//状态是正式发布的
lambdaQueryWrapper.eq(Article::getStatus, SystemConstants.ARTICLE_STATUS_NORMAL);
//置顶的文章要放在前面,isTop进行降序排序
lambdaQueryWrapper.orderByDesc(Article::getIsTop);
//按发布时间降序排序,越新发布的文章越靠前
lambdaQueryWrapper.orderByDesc(Article::getCreateTime);
//分页查询
Page<Article> page = new Page<>(pageNum, pageSize);
page(page, lambdaQueryWrapper);

//查询categoryName
List<Article> articles = page.getRecords();
//stream流方式查询
articles.forEach(article -> {
article.setCategoryName(categoryService.getById(article.getCategoryId()).getName());
//从redis中获取viewCount,若不存在则使用数据库中的值并回写redis
Long viewCount = getViewCountWithFallback(article.getId());
article.setViewCount(viewCount);
});

//封装查询结果为Vo
List<ArticleListVo> articleListVos = BeanCopyUtils.copyBeanList(page.getRecords(), ArticleListVo.class);

//获取标签
fillArticleListTags(articleListVos);

PageVo pageVo = new PageVo(articleListVos, page.getTotal());
return ResponseResult.okResult(pageVo);
}

//查询文章详情
@Override
public ResponseResult getArticleDetail(Long id)
{
//根据id查询文章
Article article = getById(id);
if (article == null) {
return ResponseResult.errorResult(AppHttpCodeEnum.SYSTEM_ERROR, "该文章不存在!");
}
//从redis中获取viewCount,若不存在则回源数据库并回写redis
Long viewCount = getViewCountWithFallback(article.getId());
article.setViewCount(viewCount);
//转化成Vo
ArticleDetailVo articleDetailVo = BeanCopyUtils.copyBean(article, ArticleDetailVo.class);

//根据分类id查询分类名
Long categoryId = articleDetailVo.getCategoryId();
Category category = categoryService.getById(categoryId);
if (category != null) {
articleDetailVo.setCategoryName(category.getName());//根据id查到了才进行下去防止空指针异常
}

//根据创建者ID查询作者昵称
Long createBy = article.getCreateBy();
String author = SystemConstants.DEFAULT_AUTHOR; // 默认作者名
if (createBy != null) {
SysUser sysUser = sysUserService.getById(createBy);
if (sysUser != null && sysUser.getNickname() != null) {
author = sysUser.getNickname();
}
}
articleDetailVo.setAuthor(author);

//计算字数统计(去除HTML标签后的纯文本字符数)
String content = article.getContent();
if (content != null) {
String textContent = content.replaceAll("<[^>]*>", "").trim();
int wordCount = textContent.length();
articleDetailVo.setWordCount(wordCount);

//计算阅读时长(分钟),假设每分钟阅读300字,最小值为1分钟
int readTime = Math.max(1, (int) Math.ceil(wordCount / 300.0));
articleDetailVo.setReadTime(readTime);
} else {
articleDetailVo.setWordCount(0);
articleDetailVo.setReadTime(1);
}

//获取标签数据
fillArticleDetailTags(articleDetailVo);

//封装响应返回
return ResponseResult.okResult(articleDetailVo);
}




PS:该系列只做为作者学习开发项目做的笔记用

不一定符合读者来学习,仅供参考


预告

后续会记录博客的开发过程

每次学习会做一份笔记来进行发表

“一花一世界,一叶一菩提”


版权所有 © 2026 云梦泽
欢迎访问我的个人网站:https://hgt12.github.io/


『博客开发日记』之修复 首次启动时无法从 redis 中获取 viewCount 的 bug
http://example.com/2026/06/15/『博客开发日记』之修复 首次启动时无法从 redis 中获取 viewCount 的 bug/
作者
云梦泽
发布于
2026年6月15日
更新于
2026年6月15日
许可协议