redis(11)

news2024/11/27 10:42:49

一)基于Set集合实现点赞功能: 

在我们的博客表当中,每一篇博客信息都有一个like字段,表示点赞的数量

需求:

1)同一个用户只能点赞一次,再次进行点赞则会被取消;

2)如果当前用户已经点赞过了,那么点赞按钮高亮显示,这个是先是依靠前端来进行实现的,是通过判断Blog类的isLike属性;

实现步骤:

1)给Blog类中添加一个isLike字段,表示当前用户是否被当前用户点过赞,如果在前端判断这个isLike存在,那么说明用户点赞过,那么直接将用户按钮变亮,如果不存在那么直接变黑,我们其实可以再次创建一张表,这张表就去记录blogID和给这个Blog点赞的userID,那么每当点赞一次,这张表就纪录了一次;

2)修改点赞功能,利用Redis的Set集合判断是否被点赞过,没有点赞过那么点赞数+1,将用户ID存储到Set集合里面,如果已经点赞过,那么点赞数-1,将用户ID从Set集合中去除

3)在博客列表页和博客详情页里面,前端就要进行查询blog中的islike字段,来进行判断当前用户是否被点赞过

@RequestMapping
@Controller
public class UserController {
    @Autowired
    private StringRedisTemplate template;
    @Autowired
    private DemoMapper mapper;
    @RequestMapping("/Java100")
    @ResponseBody
    public void InsertLike(Integer userID,Integer blogID){
        //1.正常情况下应该从session中获取到当前用户信息,此处为了方便实现直接从前端传递userID
        //2.判断当前用户是否已经针对这一篇文章点过赞了
        String key="blog:liked"+blogID;
        Boolean flag=template.opsForSet().isMember(key,userID.toString());
        if(!flag){
            //1.如果查询不到,说明当前用户没有点过赞,没有点过赞,点赞数量+1
            mapper.updateAddlike(blogID);
            //2.向redis中的set集合存放用户信息
            template.opsForSet().add(key, String.valueOf(userID));
        }else{
            //1.如果查询到了,说明用户已经点过赞了,点赞数-1
            mapper.updateSublike(blogID);
            //2.将用户ID从redis的有序集合中去除
            template.opsForSet().remove(key,String.valueOf(userID));
        }
    }
    public boolean islike(int blogID,int userID){
        String key="blog:liked"+blogID;
        Boolean flag=template.opsForSet().isMember(key,String.valueOf(userID));
//最终这个返回值要被返回的blog中设置,blog就携带了这个islike信息,前端进行接收到这个islike信息的时候,如果为true,那么按钮变亮,如果为false,那么按钮置灰
        return flag;
    }
}

二)基于SortedSet或者list实现点赞排行榜,就是找到最新点赞的5个人

 

 

@RequestMapping
@Controller
public class UserController {
    @Autowired
    private StringRedisTemplate template;
    @Autowired
    private DemoMapper mapper;
    @RequestMapping("/Java100")
    @ResponseBody
    public String InsertLike(Integer userID,Integer blogID){
        //1.正常情况下应该从session中获取到当前用户信息,此处为了方便实现直接从前端传递userID
        //2.判断当前用户是否已经针对这一篇文章点过赞了
        String key="blog:liked:"+blogID;
       Double score=template.opsForZSet().score(key,userID.toString());
        if(score==null){
            //1.如果查询不到,说明当前用户没有点过赞,没有点过赞,点赞数量+1
            mapper.updateAddlike(blogID);
            //2.向redis中的set集合存放用户信息,SortedSet的命令是zadd key value score
            template.opsForZSet().add(key,userID.toString(),System.currentTimeMillis());
            return "点赞成功";
        }else{
            //1.如果查询到了,说明用户已经点过赞了,点赞数-1
            mapper.updateSublike(blogID);
            //2.将用户ID从redis的有序集合中去除
            template.opsForZSet().remove(key,String.valueOf(userID));
            return "取消点赞成功";
        }
    }
    public boolean islike(int blogID,int userID){
        String key="blog:liked:"+blogID;
        Double score=template.opsForZSet().score(key,String.valueOf(userID));
        if(score==null){
            return false;
        }
        return true;
    }
    @RequestMapping("/Java300")
    @ResponseBody
   public List<Integer> getLastLikeUser(int blogID){
        //1.先进行生成key
       String key="blog:liked:"+blogID;
       //2.查询redis中SoreedSet最先点赞的前五名,zrange key 0 4
       Set<String> userIDs=template.opsForZSet().range(key,0,4);
       //3.解析到其中的用户ID,查找用户信息,封装到List集合中进行返回,正常是应该返回user信息的
       List<Integer> list=new ArrayList<>();
       userIDs.forEach(new Consumer<String>() {
           @Override
           public void accept(String s) {
               list.add(Integer.parseInt(s));
           }
       });
       return list;
   }
}

二)实现关注和取消关注功能

接口1:请求格式:127.0.0.1:8080/Java100?userID=5&isFollow=true

 

这里面的userID表示被关注的人的ID,这里面的isFollow是表示是关注还是取关,关注就是true,取消关注就是false

接口2:查看登陆用户是否已经关注指定用户:

127.0.0.1:8080/IsFollow/10,10表示被指定的用户

 @RequestMapping("/Follow/{userID}/{isFollow}")
   @ResponseBody
    public String Follow(@PathVariable("userID") Integer userID, @PathVariable("isFollow") Boolean isFollow, HttpSession session){
        //1.判断到底是关注还是取关
       User user= (User) session.getAttribute("user");
       //2.关注直接新增数据,取关注解删除数据
       if(isFollow){
           //还应该在来进行判断一下当前follow是否存在,防止重复进行关注
           Follow flag=mapper.selectFollow(user.getUserID(),userID);
           if(flag!=null){
               return "当前您已经关注了,不能重复进行关注";
           }
           Follow follow=new Follow();
           follow.setFollowUserID(userID);
           follow.setUserID(user.getUserID());
           mapper.InsertFollow(follow);
           return "关注成功";
       }else{
           int data=mapper.deleteFollow(user.getUserID(),userID);
           if(data==0) {
               return "取关成功";
           }else{
               return "不能重复取关";
           }
       }
   }
   @RequestMapping("/IsFollow/{userID}")
   @ResponseBody
   public String IsFollow(@PathVariable("userID") Integer followedUserID,HttpSession session){
        // 1.先获取到登录用户
        User user= (User) session.getAttribute("user");
        //2.判断用户是否关注
        Follow follow=mapper.selectFollow(user.getUserID(),followedUserID);
        if(follow==null){
            return "当前登录用户没有关注";
        }
        return "当前用户已经关注了";
   }
   @RequestMapping("/login")
   @ResponseBody
    public String login(String username,String password,HttpSession session){
        User user=mapper.login(username,password);
        if(user!=null) {
            session.setAttribute("user",user);
            return "登陆成功";
        }
        return "登陆失败";
   }

三)实现共同关注功能

需求:基于redis的恰当的数据结构,来实现共同关注功能,在博主个人主页的展现出当前用户和博主的共同好友

首先应该把一个用户关注的列表保存到redis当中,比如说当前用户关注了那些人保存到redis集合中,目标用户关注了哪些人,也需要保存到redis集合里面,这样我们进行查找共同关注好友的时候,我们可以直接进行查询两个人共同关注的好友,直接取交集就可以了,所以我们应该又该以前的接口,每当我们关注到一个人的时候,我们都应该把他存放到Set集合里面,这样真正来进行查询共同关注的好友的时候,就十分方便了,关注的用户我们不光要把她存放到数据库里面,也需要把他存放到redis里面,key就是当前登陆用户的ID,value就是

当前登录用户所进行关注的用户的ID

程序传入指定的用户ID,程序就会查询这个用户ID和当前已经登陆过的用户的共同关注好友

1)进行改造过的JAVA代码:

@RequestMapping("/Follow/{userID}/{isFollow}")
   @ResponseBody
    public String Follow(@PathVariable("userID") Integer userID, @PathVariable("isFollow") Boolean isFollow, HttpSession session){
        //1.判断到底是关注还是取关
       User user= (User) session.getAttribute("user");
       String key="follow:"+user.getUserID();
       //2.关注直接新增数据,取关注解删除数据
       if(isFollow){
           //还应该在来进行判断一下当前follow是否存在,防止重复进行关注
           Follow flag=mapper.selectFollow(user.getUserID(),userID);
           if(flag!=null){
               return "当前您已经关注了,不能重复进行关注";
           }
           Follow follow=new Follow();
           follow.setFollowUserID(userID);
           follow.setUserID(user.getUserID());
           mapper.InsertFollow(follow);
           //把当前被关注的用户ID存放到Set集合里面,zadd
           template.opsForSet().add(key,String.valueOf(follow.getFollowUserID()));
           return "关注成功";
       }else{
           int data=mapper.deleteFollow(user.getUserID(),userID);
           template.opsForSet().remove(key,String.valueOf(userID));
           if(data==0) {
               return "取关成功";
           }else{
               return "不能重复取关";
           }
       }
   }

2)现在用户进行查询

127.0.0.1:8080/common?userID=2

 @RequestMapping("/common")
    @ResponseBody
    public  List<Integer> GetCommon(Integer userID,HttpSession session){
        //1.先生成key
        String key1="follow:"+userID;
        User user= (User) session.getAttribute("user");
        String key2="follow:"+user.getUserID();
        Set<String> set=template.opsForSet().intersect(key1,key2);
        if(set==null||set.isEmpty()){
            return null;
        }
        //2.获取两人共同关注的好友
        List<Integer> list=new ArrayList<>();
        set.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                  list.add(Integer.parseInt(s));
            }
        });
        return list;
    }

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

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

相关文章

传输层:UDP协议

传输层中有两个重要的协议&#xff1a;TCP协议和UDP协议。 本博文分享的是UDP协议&#xff0c;本文将从UDP的协议格式、UDP的特定以及其缓冲区入手。 传输层 传输层的作用是负责数据能够从发送端传输到接收端&#xff0c;主要是传输策略。 端口号 端口号标识的是一个主机上进…

【AIGC提示工程 - Midjourney教程:三】如何利用Midjourney AI创作一幅杰出的艺术作品?

关注元壤教育公众号系统学习AIGC提示工程课程。 更多AIGC好博客&#xff0c;请移步访问AIGC博客派 要在Discord上使用Midjourney机器人&#xff0c;您需要输入一个指令。指令能帮助您创建图片、修改默认设置、监控用户信息以及执行其他有用的操作。如果想要生成一张图片&#x…

RHCSA之Linux目录结构

目录 Linux目录结构 Linux目录结构的特点 分区‘加载’于目录结构 Windows与Linux目录结构区别 工作目录、用户家目录及路径 Linux的文件类型大致可分为 查看文件系统类型 方法一 ls -l 路径 方法二 file 路径 RHCSA之Linux目录结构 使用树形目录结构来组织和管理文件 整个…

51单片机(十三)DS18B20温度传感器

❤️ 专栏简介&#xff1a;本专栏记录了从零学习单片机的过程&#xff0c;其中包括51单片机和STM32单片机两部分&#xff1b;建议先学习51单片机&#xff0c;其是STM32等高级单片机的基础&#xff1b;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 &#xff1a;适用于想要…

第14届蓝桥杯C++省赛(初级)真题

一、选择题&#xff08;50分&#xff09; 第 1 题 单选题&#xff08;10分&#xff09; C中&#xff0c;bool类型的变量占用字节数为 ( )。 *选择题严禁使用程序验证&#xff0c;选择题不答或答错都不扣分 A.1 B.2 C.3 D.4 第 2 题 单选题&#xff08;10分&#xff09;…

Windows 下载与安装CUDA和Pytorch【安装教程、深度学习】

参考链接&#xff1a;Windows 下安装 CUDA 和 Pytorch 跑深度学习 - 动手学深度学习v2_哔哩哔哩_bilibili 0.准备工作 请确保你是NVIDIA的显卡&#xff08;不能是AMD、集成显卡&#xff09; 1.下载CUDA 打开developer.nvidia.com/cuda-downloads&#xff0c;打开有点慢 选择…

2023/5/14 数值计算方法考试复盘

第一题 问我1-()如果减少乘除次数,那么如何做出变形。 正确解法&#xff1a; 可以利用乘法分配律&#xff0c;将1拆分成1 - 1/2! 1/2! - 1/3! 1/3! - ... - 1/n! 1/n!&#xff0c;然后将拆分出来的两项合并&#xff0c;得到&#xff1a; 1 - (1/2! - 1/2!) - (1/3! - 1/3…

支付系统设计一:支付系统产品化

系列文章目录 支付系统设计一&#xff1a;支付系统产品化 支付系统设计二&#xff1a;统一开发框架 支付系统设计三&#xff1a;渠道网关设计01-总览 支付系统设计三&#xff1a;渠道网关设计02-客户端报文解析 支付系统设计三&#xff1a;渠道网关设计03-参数验证 支付系统设…

在 Windows 上安装 Docker

一、前言 个人主页: ζ小菜鸡大家好我是ζ小菜鸡&#xff0c;让我们一起学习在 Windows 上安装Docker。如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连) 二、 Docker是什么 Docker是一个开源的应用容器引擎&#xff0c;让开发者可以打包他们的应用以及依赖包到一个可抑制的…

K8s(Kubernetes)学习(一):k8s概念及组件

Kubernetes中文文档&#xff1a;https://kubernetes.io/zh-cn/docs/home/ Kubernetes源码地址&#xff1a;https://github.com/kubernetes/kubernetes 一:Kubernetes是什么 首先要了解应用程序部署经历了以下几个时代&#xff1a; 传统部署时代&#xff1a;在物理服务器上运…

C语言——表达式求值中类型转换和优先级等问题

目录 1.隐式类型转换 2.算数转换 ​3.操作符的属性 1.隐式类型转换 C的整型算术运算总是至少以缺省整型类型的精度来进行的。 为了获得这个精度&#xff0c;表达式中的字符和短整型操作数在使用之前被转换为普通整型&#xff0c;这种转换称为整型提升。 整型提升的意义&a…

Sentinel : 服务容错(降级熔断、流量整形)

什么是服务雪崩&#xff1f; 服务雪崩效应是一种因“服务提供者的不可用”&#xff08;原因&#xff09;导致“服务调用者不可用”&#xff08;结果&#xff09;&#xff0c;并将不可用逐渐放大的现象。 我来用一个模拟场景带你感受一下服务雪崩的厉害之处。假设我有一个微服…

小世界网络评估

小世界网络评估 文章目录 小世界网络评估[toc]1、网络小世界定义2、网络评估R代码 1、网络小世界定义 现实中许多网络巨型组件都发现了“小世界特性”。小世界特性是指 网络节点间最短路径通常较小网络聚集系数较高 网络最短路径L计算公式为 L 1 n ( n − 1 ) ∑ i ⩾ j d…

【JZ-7Y-16静态中间继电器 触点容量大、电阻小 抗干扰强 JOSEF约瑟】

系列型号&#xff1a; JZ-7Y-15静态中间继电器&#xff1b; JZ-7J-15静态中间继电器&#xff1b; JZ-7L-15静态中间继电器&#xff1b; JZ-7D-15静态中间继电器&#xff1b; JZ-7Y-16静态中间继电器&#xff1b; JZ-7J-16静态中间继电器&#xff1b; JZ-7L-16静态中间继…

自动化渗透测试自动化挖掘src(2)

文章目录 前言思路ICP备案子域名枚举收集可用服务漏洞攻击 前言 上一谈我们讨论了自动化渗透测试的实验&#xff0c;但是他过于依赖fofa&#xff0c;不得不承认&#xff0c;fofa在资产收集这方面做的确实很厉害&#xff0c;但是就是需要花钱&#xff0c;那有没有不需要花钱都手…

UI GameObject可以在Scene View中显示,但是在Game View不能显示

出现UI GameObject可以在Scene View中显示&#xff0c;但是在Game View不能显示这种问题&#xff0c;可能有很多种原因&#xff0c;例如Layer设定、Camera Clipping设定、font assets等问题。 对于TextMeshPro&#xff0c;还有Material Set的问题&#xff0c;见这篇文章。 而我…

PHP 8.2:它对 WordPress、插件和开发者意味着什么?

PHP 8.2.0于 2022 年 12 月 8 日首次亮相。作为一项重大更新&#xff0c;它带来了性能改进和更简单的语法。PHP 8.2 引入了更高的类型安全性作为一项功能&#xff0c;将null、false和true作为独立类型。可能挑战 WordPress 开发人员的最大变化之一是添加了只读类&#xff0c;它…

基于SSM/Layui框架的火影忍者风格学生宿舍管理系统

目录 1、项目简介 2、使用技术 3、功能介绍 实现的主要功能&#xff1a; 4、所有页面 基于SSM/Layui框架的火影忍者风格学生宿舍管理系统 1、项目简介 本项目是一套基于SSMLayui的高校宿舍管理系统&#xff0c;主要针对计算机相关专业的正在做毕业设计的学生和需要项目实…

搭建动态网站( Discuz论坛)

目录标题 搭建动态网站1.linux平台部署web服务2.配置web服务&#xff08;1&#xff09;安装web服务&#xff08;2&#xff09;根据配置定义加载网页资源文件的路径&#xff08;3&#xff09;根据配置创建资源文件&#xff08;4&#xff09;重启服务 3.部署mariadb数据库4.安装P…

【力扣周赛】第345场周赛

【力扣周赛】第345场周赛 6430&#xff1a; 找出转圈游戏输家题目描述解题思路 6431&#xff1a; 相邻值的按位异或题目描述解题思路 6433&#xff1a; 矩阵中移动的最大次数题目描述解题思路 6432&#xff1a; 统计完全连通分量的数量题目描述解题思路 6430&#xff1a; 找出转…