SpringBoot+Redis实现浏览量+1

news2024/12/28 15:49:50

当用户点击新闻查看详情后,数据库新闻的浏览量字段要加一,当在高并发场景下,很多人查看新闻详情直接操作数据库使浏览量字段加一对数据库压力过大,并且容易造成脏数据,这里结合redis实现浏览量加一。

业务逻辑:

①、项目初始化,缓存所有新闻的浏览量Map

②、点击详情后,相应新闻的浏览量自增加一

③、定时器使redis数据写入数据库

④、查询文章浏览量以redis为准

新闻entity:

@Data
@TableName(value ="app_news")
public class AppNews {
    @TableId
    private String newsId;

    private String newsTitle;

    private String newsContent;

    private Integer viewNum;

}

先来第一步,项目启动初始化把新闻浏览量存入redis:

在新闻业务实现类添加一个方法,使用@PostConstruct注解表示项目启动后自动执行该方法

@Resource
private RedisCache redisCache;

@PostConstruct
public void init() {
    log.info("新闻浏览量写入缓存开始==>");
    List<AppNews> appNewsList = list();
    Map<String, Integer> newsViewMap = appNewsList.stream().collect(Collectors.toMap(AppNews::getNewsId, AppNews::getViewNum));
    redisCache.setCacheMap(CacheConstants.NEWS_VIEW_NUM_KEY, newsViewMap);
    log.info("<==新闻浏览量写入缓存成功");
}

写入Map成功:新闻id对应浏览量

在这里插入图片描述

下面是新闻查看详情接口,新增业务新闻阅读量加一(ps:当然如果你想优雅也可以使用AOP):

@Transactional
@GetMapping("/{newsId}")
public AjaxResult getDetails(@PathVariable(value = "newsId") String newsId) {
    AppNews appNews = appNewsService.getNewsDetails(newsId);
    // 新闻阅读量加一
    appNewsService.viewNumIncrease(newsId);
    return AjaxResult.success(appNews);
}

appNewsService.viewNumIncrease(newsId);方法具体实现:

@Override
public void viewNumIncrease(String newsId) {
    // 缓存中阅读量自增一
    redisCache.incrementCacheMapValue(CacheConstants.NEWS_VIEW_NUM_KEY, newsId, 1);
}

redisCache中封装对应方法:

public void incrementCacheMapValue(String key, String hKey, long v) {
    redisTemplate.boundHashOps(key).increment(hKey, v);
}

此时阅读量在缓存中自增一了,接下来查看新闻详情需要把redis的浏览量查出来返回而不是数据库

查询新闻详情方法修改:

@Override
public AppNews getNewsDetails(String newsId) {
    LambdaQueryWrapper<AppNews> queryWrapper = new LambdaQueryWrapper<>();
    queryWrapper.eq(StringUtil.isNotEmpty(newsId), AppNews::getNewsId, newsId);
    AppNews one = getOne(queryWrapper);
    this.getNewsViewNumFromRedis(one);
    return one;
}
private void getNewsViewNumFromRedis(AppNews appNews) {
    appNews.setViewNum(redisCache.getCacheMapValue(CacheConstants.NEWS_VIEW_NUM_KEY, appNews.getNewsId()));
}

再写一个定时器定时同步浏览量即可:

@Component
public class updateNewsViewNumTask {

    private static final Logger log = LoggerFactory.getLogger(updateNewsViewNumTask.class);

    @Resource
    private RedisCache redisCache;

    @Resource
    private AppNewsService appNewsService;

    @Scheduled(cron = "0/10 * * * * ?")
    public void updateViewCount() {
        log.info("开始从redis更新新闻浏览量==>");
        //获取redis中的浏览量
        Map<String, Integer> viewNumMap = redisCache.getCacheMap(CacheConstants.NEWS_VIEW_NUM_KEY);
        List<AppNews> newsList = viewNumMap.entrySet().stream().map(entry -> {
            AppNews an = new AppNews();
            an.setNewsId(entry.getKey());
            an.setViewNum(entry.getValue());
            return an;
        }).collect(Collectors.toList());
        //更新数据库
        appNewsService.updateBatchById(newsList);
        log.info("<==新闻浏览量数据库与redis同步成功");
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/549576.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能Python-pythonfoo

Pythonfoo: 优秀的Python库提高开发效率 Python是一门被广泛应用的动态编程语言&#xff0c;提供了各种各样的库来帮助开发人员完成不同类型的任务。在这些Python库中&#xff0c;Pythonfoo是一款旨在提高开发效率和代码简洁性的出色的Python库。 什么是Pythonfoo&#xff1f…

一种用于超低功耗无线传感器网络的消息传递算法(Matlab代码实现)

目录 &#x1f4a5;1 概述 &#x1f4da;2 运行结果 &#x1f389;3 参考文献 &#x1f468;‍&#x1f4bb;4 Matlab代码 &#x1f4a5;1 概述 无线传感器网络是由一定数量的无线传感器节点组成的网络系统,各节点可采集环境数据并通过无线通信进行数据传输,目前已广泛应用…

使用cubeMX生成USB HID设备

一&#xff0c;简介 本文主要介绍如何使用stm32F407开发板和cubeMX生成USB FS HID设备&#xff0c;供参考。 二&#xff0c;操作步骤 本次总共分以下几个步骤&#xff1a; 1&#xff0c;创建cubeMX工程&#xff0c;并配置HID&#xff0c;生成工程代码&#xff1b; 2&#xf…

光伏防逆流系统的介绍

安科瑞虞佳豪 5月17日&#xff0c;新疆和田地区洛浦县国家电投洛浦光伏电站&#xff0c;今年2月刚刚并网发电的200兆瓦光伏发电项目坐落于戈壁滩上&#xff0c;占地5500亩的368004块光伏面板在阳光照射下熠熠生辉&#xff0c;为和田地区经济社会发展持续提供着绿色能源。 洛浦…

HNU-操作系统OS-实验Lab6

OS_Lab6_Experimental report 湖南大学信息科学与工程学院 计科 210X wolf (学号 202108010XXX) 实验目的 理解操作系统的调度管理机制熟悉 ucore 的系统调度器框架,以及缺省的Round-Robin 调度算法基于调度器框架实现一个(Stride Scheduling)调度算法来替换缺省的调度算…

第12章_MySQL数据类型精讲

第12章_MySQL数据类型精讲 1. MySQL中的数据类型 类型类型举例整数类型TINYINT、SMALLINT、MEDIUMINT、INT(或INTEGER)、BIGINT浮点类型FLOAT、DOUBLE定点数类型DECIMAL位类型BIT日期时间类型YEAR、TIME、DATE、DATETIME、TIMESTAMP文本字符串类型CHAR、VARCHAR、TINYTEXT、TE…

chatgpt赋能Python-pythondeque函数

Python deque函数&#xff1a;高效地操作双向队列 介绍 在Python中&#xff0c;deque函数是一个非常重要的内置函数&#xff0c;用于创建双向队列。双向队列是一个序列容器&#xff0c;可以从两端添加或删除元素&#xff0c;这使得它成为许多常见问题的解决方案。deque函数是…

Vue--》深入理解 Vue 3 导航守卫,掌握前端路由的灵魂技能!

目录 vue3导航守卫讲解与使用 element-ui的安装与使用 配置路由和设置路径别名 设置登录页面并实现规则跳转 设置导航前置守卫 设置导航后置守卫 其他路由相关操作 vue3导航守卫讲解与使用 导航守卫是在 Vue Router 中提供的一种功能&#xff0c;它允许你在切换路由之前…

chatgpt赋能Python-pythonfirst

PythonFirst&#xff1a;Python编程新手的最佳起点 作为一门简洁而又强大的编程语言&#xff0c;Python在过去的几年中得到了越来越多的关注和应用。它广泛应用于数据分析、人工智能、Web开发、自动化等领域&#xff0c;成为了许多程序员的首选语言。如果你也是刚刚开始接触Py…

有哪些简单而知道的人少的excel操作技巧?

以下是 Excel 里鲜为人知而又简单、逆天的操作技巧&#xff1a; 1. 快速选中数据区域&#xff1a;双击数据区域左上角的方格即可快速选中整个数据区域。 2. 使用自动筛选快速查找和筛选数据&#xff1a;在 Excel 数据表中&#xff0c;使用自动筛选可以快速找到和筛选特定数据…

【Robot Dynamics Lecture Notes学习笔记之浮动基动力学】

Robot Dynamics Lecture Notes学习笔记之浮动基动力学 Contact ForcesSoft Contact Model Contact Forces from Constraints Constraint Consistent DynamicsContact Switches and Impact CollisionsImpulse TransferEnergy Loss 浮动基座系统的广义坐标分别由驱动关节坐标 q j…

小程序-基础加强(二):使用npm包

使用npm包 1.小程序对npm的支持与限制 目前&#xff0c;小程序中已经支持使用npm安装第三方包&#xff0c;从而来提高小程序的开发效率。但是&#xff0c;在小程序中使用npm包有如下3个限制&#xff1a; ①不支持依赖于Node.js内置库的包 ②不支持依赖于浏览器内置对象的包 …

Springboot +spring security,登录表单进阶配置及原理分析

一.简介 登录表单配置实操 二.创建项目 如何创建一个SpringSecurity项目&#xff0c;前面文章已经有说明了&#xff0c;这里就不重复写了。 三.配置默认用户信息 配置文件添加如下用户信息&#xff0c;代码如下&#xff1a; spring:security:user:name: lglbcpassword: 1…

HNU数据结构与算法分析-作业7-算法设计技术

1. (简答题, 10分)请简述分治法所能解决的问题一般具有哪些特征&#xff1f; 2. (简答题, 10分)请简述动态规划法的四个求解步骤。 3. (简答题, 10分)请比较动态规划法和贪心法&#xff0c;并写出两者的区别。 4. (简答题, 10分)请写出分支限界法和回溯法的区别。 二. 算法设计…

chatgpt赋能Python-pythonendswith

Python endswith方法&#xff1a;介绍、用法和示例 在编程中&#xff0c;经常需要查找字符串是否以特定字符结尾。Python提供了一个方便易用的方法——endswith()。 什么是Python endswith()方法&#xff1f; Python endswith()方法是用于检查字符串是否以特定子字符串结尾的…

第六章总结-莫凡商城的注册、登录功能

1.微信小程序表单组件 1.1button按钮组件 type的属性值有三种 primary 绿色default 白色warn 红色 除了这种方式可以设置按钮大小&#xff0c;还有其他的通过视图来控制按钮的方式&#xff0c;因为我们知道&#xff0c;微信小程序的按钮并不都是这三种颜色。其他方式比如把按…

Web APIs之DOM

一.Web API基本认知 二.获取DOM对象 三.操作元素内容 四. 操作元素属性 五.定时器-间歇函数 一、Web API基本认知 *作用和分类 *什么是DOM *DOM树 *DOM对象 1.作用和分类 &#xff08;1&#xff09;作用&#xff1a;使用JS去操作html和浏览器 &#xff08;2&#xff09…

service mesh学习

背景 单体服务的痛点导致单体服务被拆分为多个微服 每个微服必须要解决负载均衡、服务发现、熔断等功能 为了让上层开发更加快速和无需关注通用能力&#xff0c;在网络栈和应用业务层之间抽出一个透明网络代理层。 Service Mesh 轻量级网络代理&#xff0c;负责微服之间的通…

H5 实现蜂巢(六边形)导航,支持用户交互和动态添加,纯css实现无需布局计算

最近公司的项目出了版新的UI设计图&#xff0c;所以准备进行样式改版 而其中就有个导航要改成蜂巢(六边形)导航&#xff0c;当我看到时其实也挺迷糊的。 说一下我一开始的想法哈&#xff1a; 我一开始是打算使用背景颜色线性渐变 或者 用4个子元素覆盖4角 来实现 六边形的视觉…