基于SpringBoot+redis实现一个简单的点赞功能

2023-11-01

点赞操作比较频繁,而且比较随意,所以数据变更很快,如果用mysql,会对mysql产生很大的压力,于是决定使用Redis,防止数据丢失,所以会定期将数据持久化同步到mysql中。

一、Redis 缓存设计及实现

1.1 Redis 安装及运行

linux中的gcc是由GNU推出的一款功能强大的、性能优越的多平台编译器。gcc编译器能将C、C++语言源程序和目标程序编译、连接成可执行文件。

Redis 安装请查阅上一篇教程。

1.2 Redis 与 SpringBoot 项目的整合

1.在 pom.xml 中引入依赖

    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>va

2.编写 Redis 配置类

    @SuppressWarnings("all")
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();

        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();

        return template;
    }

1.3 Redis 的数据结构类型

Redis 可以存储键与5种不同数据结构类型之间的映射,这5种数据结构类型分别为String(字符串)、List(列表)、Set(集合)、Hash(散列)和 Zset(有序集合)。

下面来对这5种数据结构类型作简单的介绍:
在这里插入图片描述
前端点赞图标和手动模拟用户id的编写

      模拟用户ID:<input type="text" id="userId"><br>
      <span th:if="${isLike==false}">
        <span class="glyphicon glyphicon-thumbs-up zan" style="font-size: 25px; cursor: pointer" ></span>
      </span>
      <span th:if="${isLike==true}">
        <span class="glyphicon glyphicon-thumbs-up red zan" style="font-size: 25px; cursor: pointer" ></span>
      </span>
      <span id="count" th:text="${count}"></span>
    </div>
    <br>
    <div id="show"></div>ml

在这里插入图片描述
js和css样式

  <style>
    .red{
      color: red;
    }
  </style>
  <script>
    $(function () {
      $(".zan").click(function () {
        //1.获取用户id--判断是否为空
        let userId=$("#userId").val();
        if (userId.trim()==''){
          alert("必须输入用户id")
          return;
        }
        //2.获取纹章id
        let newsId=$("#newsId").val();
        alert(newsId);
        //3.ajax请求处理
        let data={userId:userId,newsId:newsId}
        $.getJSON('/news/like',data,function (v) {
          //返回值--1 出错了 如果返回 最新数据写到数量的位置
          if (v==-1){
            alert("点赞失败");
          }else {
            $("#count").text(v);
            $(".zan").addClass("red");
          }
        })
      })
      $("#count").click(function () {
        let newsId=$("#newsId").val();
        $.getJSON('/news/queryLikeUser', {newsId:newsId},function (v) {
            for (let id of v){
              $("#show").append(id+" ,")
            }
        })
      })
    })

后端控制层Controller

 /**
     * 点赞
     * */
    @RequestMapping("/like")
    @ResponseBody
    public long like(Integer userId,Integer newsId){
        return newsService.like(userId,newsId);
    }

service接口

Long like(Integer userId, Integer newsId);

 long queryCount(Integer newsId);

service实现类

public static final String REDIS_NEWS_ZAN_KEY="zan";
    @Autowired
    private RedisTemplate redisTemplate;
 @Override
    public Long like(Integer userId, Integer newsId) {
        long count=-1;
//写入redis 用户id和新闻id        redisTemplate.opsForSet().add(REDIS_NEWS_ZAN_KEY+newsId,userId);
//算出点赞的数量         count=redisTemplate.opsForSet().size(REDIS_NEWS_ZAN_KEY+newsId);
        return count;
    }

@Override
    public long queryCount(Integer newsId) {

        return redisTemplate.opsForSet().size(REDIS_NEWS_ZAN_KEY+newsId);
    }

因为先不写入MySQL数据库,先不操作dao层,后续进行添加

然后添加展示点赞用户列表
controller

/**
 * 点赞用户列表
 * */
    @RequestMapping("/queryLikeUser")
    @ResponseBody
    public Set queryLikeUser(Integer newsId){
        return newsService.queryLikeUser(newsId);
    }

service接口

 boolean checkIsLike(int userId, Integer newsId);
  Set queryLikeUser(Integer newsId);

service实现

@Override
    public boolean checkIsLike(int userId, Integer newsId) {

        return redisTemplate.opsForSet().isMember(REDIS_NEWS_ZAN_KEY+newsId,userId);
    }
```@Override
    public Set queryLikeUser(Integer newsId) {

        return  redisTemplate.opsForSet().members(REDIS_NEWS_ZAN_KEY+newsId);
    }
以上就是简易版点赞功能的设计与实现,其余业务后续再更新。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于SpringBoot+redis实现一个简单的点赞功能 的相关文章

  • Java中有没有一种方法可以通过名称实例化一个类?

    我正在寻找问题 从字符串名称实例化一个类 https stackoverflow com questions 9854900 instantiate an class from its string name它描述了如何在有名称的情况下实例
  • 不同帐户上的 Spring Boot、JmsListener 和 SQS 队列

    我正在尝试开发一个 Spring Boot 1 5 应用程序 该应用程序需要侦听来自两个不同 AWS 帐户的 SQS 队列 是否可以使用 JmsListener 注解创建监听器 我已检查权限是否正确 我可以使用 getQueueUrl 获取
  • 如何通过 javaconfig 使用 SchedulerFactoryBean.schedulerContextAsMap

    我使用 Spring 4 0 并将项目从 xml 移至 java config 除了访问 Service scheduleService 带注释的类来自QuartzJobBean executeInternal 我必须让它工作的 xml 位
  • 使用 LinkedList 实现下一个和上一个按钮

    这可能是一个愚蠢的问题 但我很难思考清楚 我编写了一个使用 LinkedList 来移动加载的 MIDI 乐器的方法 我想制作一个下一个和一个上一个按钮 以便每次单击该按钮时都会遍历 LinkedList 如果我硬编码itr next or
  • 使用 MongoDB 作为我们的主数据库,我应该使用单独的图数据库来实现实体之间的关系吗?

    我们目前正在为一家专业公司内部实施类似 CRM 的解决方案 由于存储信息的性质以及信息的不同值和键 我们决定使用文档存储数据库 因为它完全适合目的 在本例中我们选择 MongoDB 作为此 CRM 解决方案的一部分 我们希望存储实体之间的关
  • 如何在java中将一个数组列表替换为另一个不同大小的数组列表

    我有两个大小不同的数组列表 如何从此替换 ArrayList
  • HSQL - 识别打开连接的数量

    我正在使用嵌入式 HSQL 数据库服务器 有什么方法可以识别活动打开连接的数量吗 Yes SELECT COUNT FROM INFORMATION SCHEMA SYSTEM SESSIONS
  • 如何获取之前的URL?

    我需要调用我的网络应用程序的 URL 例如 如果有一个从 stackoverflow com 到我的网站 foo com 的链接 我需要 Web 应用程序 托管 bean 中的 stackoverflow 链接 感谢所有帮助 谢谢 并不总是
  • 在 Jar 文件中运行 ANT build.xml 文件

    我需要使用存储在 jar 文件中的 build xml 文件运行 ANT 构建 该 jar 文件在类路径中可用 是否可以在不分解 jar 文件并将 build xml 保存到本地目录的情况下做到这一点 如果是的话我该怎么办呢 Update
  • Java 集合的并集或交集

    建立并集或交集的最简单方法是什么Set在 Java 中 我见过这个简单问题的一些奇怪的解决方案 例如手动迭代这两个集合 最简单的单行解决方案是这样的 set1 addAll set2 Union set1 retainAll set2 In
  • java.lang.IllegalStateException:提交响应后无法调用 sendRedirect()

    这两天我一直在尝试找出问题所在 我在这里读到我应该在代码中添加一个返回 我做到了 但我仍然得到 java lang IllegalStateException Cannot call sendRedirect after the respo
  • 将 MOXy 设置为 JAXB 提供程序,而在同一包中没有属性文件

    我正在尝试使用 MOXy 作为我的 JAXB 提供程序 以便将内容编组 解组到 XML JSON 中 我创建了 jaxb properties 文件 内容如下 javax xml bind context factory org eclip
  • 如何在用户输入数据后重新运行java代码

    嘿 我有一个基本的java 应用程序 显示人们是成年人还是青少年等 我从java开始 在用户输入年龄和字符串后我找不到如何制作它它们被归类为 我希望它重新运行整个过程 以便其他人可以尝试 的节目 我一直在考虑做一个循环 但这对我来说没有用
  • 如何访问JAR文件中的Maven资源? [复制]

    这个问题在这里已经有答案了 我有一个使用 Maven 构建的 Java 应用程序 我有一个资源文件夹com pkg resources 我需要从中访问文件 例如directory txt 我一直在查看各种教程和其他答案 但似乎没有一个对我有
  • 如何在谷歌地图android上显示多个标记

    我想在谷歌地图android上显示带有多个标记的位置 问题是当我运行我的应用程序时 它只显示一个位置 标记 这是我的代码 public class koordinatTask extends AsyncTask
  • Java 和 Python 可以在同一个应用程序中共存吗?

    我需要一个 Java 实例直接从 Python 实例数据存储中获取数据 我不知道这是否可能 数据存储是否透明 唯一 或者每个实例 如果它们确实可以共存 都有其单独的数据存储 总结一下 Java 应用程序如何从 Python 应用程序的数据存
  • logcat 中 mSecurityInputMethodService 为 null

    我写了一点android应显示智能手机当前位置 最后已知位置 的应用程序 尽管我复制了示例代码 并尝试了其他几种解决方案 但似乎每次都有相同的错误 我的应用程序由一个按钮组成 按下按钮应该log经度和纬度 但仅对数 mSecurityInp
  • 使用 AsyncTask 传递值

    我一直在努力解决这个问题 但我已经到了不知道该怎么办的地步 我想做的是使用一个类下载文件并将其解析为字符串 然后将该字符串发送到另一个类来解析 JSON 内容 所有部件都可以单独工作 并且我已经单独测试了所有部件 我只是不知道如何将值发送到
  • 干净构建 Java 命令行

    我正在使用命令行编译使用 eclipse 编写的项目 如下所示 javac file java 然后运行 java file args here 我将如何运行干净的构建或编译 每当我重新编译时 除非删除所有内容 否则更改不会受到影响 cla
  • Spring Boot 无法更新 azure cosmos db(MongoDb) 上的分片集合

    我的数据库中存在一个集合 documentDev 其分片键为 dNumber 样本文件 id 12831221wadaee23 dNumber 115 processed false 如果我尝试使用以下命令通过任何查询工具更新此文档 db

随机推荐

  • Android实战篇 阅读并同意“用户协议”与“隐私政策” 【Kotiln / Java】

    一 前言 SpannableStringBuilder 1 SpannableStringBuilder和SpannableString的区别类似与StringBuilder String 2 SpannableStringBuilder可
  • Qt 添加动态库.so文件的正确方法

    1 选中项目 右键 选中 Add Library 完成后 内容自动更新到Pro文件 我原来认为是手写的 qt添加动态库 so文件的正确方法 qt so CSDN博客
  • 软件测试—学习路线

    1 入门期 手工测试 利用测试用例去检验程序是否正确输出结果 通俗来说就是在编写程序结束后自己会运行几个例子来检查程序是否正确运行 而这样的行为就是手工测试 不过企业上手工测试的测试用例会比较刁钻 容易发现自动化测试发现不了的问题 不过这种
  • 用Openssl建立私有CA并颁发证书

    1 建立CA根证书 1 1生成私钥 openssl req newkey rsa 1024 sha1 config myopenssl cnf keyout rootkey pem out rootreq pem days 3650 1 2
  • 联想笔记本Ubuntu14.04 无法连接无线网络,WiFi已通过硬件开关禁用

    最近给一台联想笔记本装Ubuntu14 04系统 开机后屏幕右上角没有WiFi信息出现 倒是有个灰体的 WiFi已通过硬件开关禁用 看到这我的内心奔腾而过一群草原动物 开机就关WiFi 不能连WiFi的笔记本还能搞啥 莫着急 慢慢来 看这字
  • HDFS常见的问题和处理方法积累

    Hadoop常见问题与解决办法 问题1 reduce预处理阶段shuffle时获取已完成的map的输出失败次数超过上限 问题描述 问题剖析 解决方案 问题2 Too many fetch failures 问题描述 问题剖析 解决方案 问题
  • 解决el-select下拉框有值但是无法选中的问题

    问题描述 在某次开发项目时 发现el select组件无法选中数据了 下拉框中数据可以正常展示 数据是通过接口获取的 解决方案 在 el select 中加一个 change 的事件刷新一下 代码如下
  • top命令的使用和查看某个进程占用的系统内存大小

    一 top指令查看CPU状态和内存使用状态 1 查看CPU占用率 CPU 上次更新到现在的CPU时间占用百分比 2 查看内存占用率 MEM 进程使用的物理内存百分比 3 RES 进程使用的 未被换出的物理内存大小 单位kb RES CODE
  • go通过数组(切片)构建菜单树结构

    有这样的一组节点 每个节点包含自己的Id 还有父Id Parent Id 包含children指针数组 但是children是空 需要根据id和parentId把cihldren填充上 实现了如下的方法 type TreeNode inte
  • JAVA TCP客户端和服务器端简单实例

    客户端 package com example demo import java io BufferedReader import java io InputStreamReader import java io PrintWriter i
  • 详解Java中的byte类型(补充内容)

    写在前面 大家有时候可能会对Java中出现的byte类型有些疑惑 今天就来内化这些知识点 这个算是对其他博客的一个补充 内容很少 byte 在Java中 byte占据一个字节 也就是8的bite位 public static void ma
  • Kaiwii

    http blog csdn net kaiwii article details 7478038
  • qt 16进制字符串 转换为 二进制 字节流

    代码 include
  • 找出10个被打乱的数中被拿出的一个数

    include
  • RuoYi-弹出新窗口选择数据回显到父页面

    这里只贴出关键代码 其他代码需要自行编写 返回值处理根据实际需求来 目前是只取第一条 因为选择页面是单选行 表单页面新加方法 选择社区 function selectCommunity var url ctx community selec
  • 深度

    解码区块链 专题文章三 区块链的安全基础架构及构想 近期 国家发改委明确 区块链 被纳入新基建定义和范围 作为一项能够打通各个技术及领域的基础技术 区块链被认为将在各行业深度融合 新领域拓展 新场景新应用开发等方面潜力无限 解码区块链 内容
  • js 小技巧 ( 根据不同的状态生成不同的颜色和状态 )

    HTML 解决办法 动态绑定 color 然后 根据 三元表达式 进行处理 js 解决办法 动态绑定 color 然后 根据在每个数据的后面添加color属性 可能有的人会问vueb不能用不然不会双向绑定 确实vue要使用vueset 但是
  • 他人工作多年后的总结

    1 找一个好公司 精通至少一门语言及其框架 专注做5到10年 先有深度再有广度 不要为了高工资过早转向管理角色 2 从长远来看 拥有个人项目 阅读 写博客和参加访谈都会有助于你成为一个更好的开发人员 3 成为开发者社区的一部分 努力参加线上
  • qt写C++(引用的妙处,内联函数)

    首先看什么是引用 引用和取地址很像 容易混淆 单独出现 a就是对a这个变量取地址 如果是int a 就是声明这是一个引用 引用 include
  • 基于SpringBoot+redis实现一个简单的点赞功能

    点赞操作比较频繁 而且比较随意 所以数据变更很快 如果用mysql 会对mysql产生很大的压力 于是决定使用Redis 防止数据丢失 所以会定期将数据持久化同步到mysql中 一 Redis 缓存设计及实现 1 1 Redis 安装及运行