redis(11)

一)基于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;
    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STL-deque容器

双端数组&#xff0c;可以对头端进行插入删除操作 deque 容器和 vecotr 容器有很多相似之处&#xff0c;比如&#xff1a; deque 容器也擅长在序列尾部添加或删除元素&#xff08;时间复杂度为O(1)&#xff09;&#xff0c;而不擅长在序列中间添加或删除元素。deque 容器也可…

win部署CAS服务并使用

前提描述&#xff1a;通过本次了解cas是个什么东西&#xff0c;并使用它。 cas为oss(单点登录)的一种实现方案。要实现cas单点登录&#xff0c;首先需要部署cas的server服务。 CAS是Central Authentication Service的缩写&#xff0c;中央认证服务&#xff0c;。 一、安装CAS…

VMware NSX-T Data Center 3.2.3 - 数据中心网络全栈虚拟化

VMware NSX-T Data Center 3.2.3 - 数据中心网络全栈虚拟化 重要更新&#xff1a;修复 136 个 bug。 请访问原文链接&#xff1a;https://sysin.org/blog/vmware-nsx-t-3/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org VMwa…

OpenGL高级-实例化

知识点 假如你有一个有许多模型的场景&#xff0c;而这些模型的顶点数据都一样&#xff0c;只是进行了不同的世界空间的变换。想象一下&#xff0c;有一个场景中充满了草叶&#xff1a;每根草都是几个三角形组成的。你可能需要绘制很多的草叶&#xff0c;最终一次渲染循环中就肯…

【开源之夏 2023】欢迎报名 Dragonfly、Kata Containers、Nydus 社区项目!

开源之夏是由“开源软件供应链点亮计划”发起并长期支持的一项暑期开源活动&#xff0c;旨在鼓励在校学生积极参与开源软件的开发维护&#xff0c;促进优秀开源软件社区的蓬勃发展&#xff0c;培养和发掘更多优秀的开发者。 活动联合国内外各大开源社区&#xff0c;针对重要开…

[一篇读懂]C语言十二讲:栈与队列和真题实战

[一篇读懂]C语言十二讲&#xff1a;栈与队列和真题实战 1. 与408关联解析及本节内容介绍1 与408关联解析2 本节内容介绍 2. 栈(stack)的原理解析2.1 **栈&#xff1a;只允许在一端进行插入或删除操作的线性表**2.2 栈的基本操作2.3 栈的顺序存储2.4 栈的链表存储 3. 初始化栈 -…

MySQL学习笔记

一、mysql环境安装 服务管理工具&#xff08;省略&#xff09; 二、Mysql DB2 Sybase Oracle SQL Server Mysql Access MangoDB(noSQL) Apache/nginx服务器&#xff1a; LAMP LinuxApacheMysqlPHP LNMP LinuxNginxMysqlPHP WAMP windowApacheMysqlPHP SQL: DDL(数据定…

【进程间通信 之 通信的建立】

目录&#xff1a; 前言进程间通信的目的进程间通信的方式管道1.匿名管道简单示例1 - 消息传输五个特性四种场景简单示例2 - 进程控制对管道的深入理解 2.命名管道简单示例3 -- 不相关进程间通信 system V共享内存简单示例4 - 通知事件消息传输 总结 前言 打怪升级&#xff1a;…

MyBatis学习 (一) 配置文件解析流程

MyBatis源码学习 最近在学习MyBatis的代码。记录下 首先下载下源码&#xff1a; https://github.com/mybatis/parent https://github.com/mybatis/mybatis-3 parent为父控依赖。也需要下载。 入口 InputStream inputStream null; try {// 获取配置文件inputStream Reso…

为AIGC敲响警钟!千亿级赛道为何成了作恶温床?

‍数据智能产业创新服务媒体 ——聚焦数智 改变商业 随着人工智能通用大模型的问世&#xff0c;全球对AIGC技术的强大潜力有了更加深刻的认识。然而&#xff0c;这也引发了诸多关于AIGC技术可信度、隐私保护以及知识产权等问题的争议&#xff0c;引起了广泛关注。 5月9日&…

开源单用户客服系统源码-上传附件功能-elementui 异步上传文件【唯一客服开发商】...

之前开源的单用户客服系统&#xff0c;上传附件成功后&#xff0c;还不能展示出文件形式&#xff0c;今天把上传展示出文件形式给开发完善一下。 我想要实现的效果是&#xff0c;展示出文件的名称和大小信息 后端返回一个带有文件信息的json结果&#xff0c;前端把该信息组织一…

ubuntu系统配置大恒相机驱动并读取ros话题

文章目录 0. 说明1. 安装大恒相机sdk1.1 下载1.2 安装sdk(用于配置ip和调试相机参数)(1) 电脑网卡配置(网卡固定ip)(2)查看相机图像以及配置相机参数 2. 安装ros驱动包(注&#xff1a;大恒相机官方没ros驱动)2.0 正确流程2.1 错误示范2.1 报错1--缺包2.2 报错2--包编译顺序问题…

arduino 导入 Brain 库

一、引言 最近在做一个可以用脑电波控制的arduino小车&#xff0c;需要用到Brain这个库&#xff0c;而且需要自己导入才能使用。之前试了很多方法&#xff0c;导入成功了&#xff0c;过了几个月又忘记怎么导入了&#xff0c;今天想起来记录一下&#xff0c;好记性不如烂笔头。 …

Java集合类

目录 一、整体架构图 二、List集合类(有序的&#xff0c;可重复的) 1.顺序列表ArrayList 2.链式列表LinkedList 三、Set集合类(不可重复) 1.HashSet(哈希集合) 2.LinkedHashSet(链式哈希集合) 3.TreeSet(树形集合) 四、Map集合类(无序&#xff0c;键唯一&#xff0c;值…

MySQL实战之主从数据同步机制

主从同步的重要性&#xff1a; 解决数据可靠性的问题需要用到主从同步&#xff1b;解决 MySQL 服务高可用要用到主从同步&#xff1b;应对高并发的时候&#xff0c;还是要用到主从同步。 一、MySQL 主从同步流程 当客户端提交一个事务到 MySQL 的集群&#xff0c;直到客户端收…

跨域时怎么处理 cookie?

前言 一个请求从发出到返回&#xff0c;需要浏览器和服务端的协调配合。浏览器要把自己的请求参数带给服务端&#xff0c;服务端校验参数之后&#xff0c;除了返回数据&#xff0c;也可能会顺便把请求是否缓存&#xff0c;cookie等信息告诉浏览器。当请求是跨域请求的时候&…

项目调研 | Loopring研究报告

一、项目简介及愿景 Loopring协议是一个专为应用程序开发的 zkRollup 协议、一个中继器、一个 L2 非托管交易所、一个智能钱包。用户可以在其中使用、交易和存储资产&#xff0c;同时让资产获得增长。 上述Loopring这些Title具体详情如下&#xff1a; 作为协议&#xff0c;Loop…

[Golang] 设计模式以及单例设计模式实例实现

&#x1f61a;一个不甘平凡的普通人&#xff0c;致力于为Golang社区和算法学习做出贡献&#xff0c;期待您的关注和认可&#xff0c;陪您一起学习打卡&#xff01;&#xff01;&#xff01;&#x1f618;&#x1f618;&#x1f618; &#x1f917;专栏&#xff1a;算法学习 &am…

金3银四结束了,回顾一下我2个月面试的公司....

金三银四结束了&#xff0c;还没有 offer 的同学不要气馁&#xff0c;该来的迟早会来。楼主从 年底 月有想法跳槽开始准备春招&#xff0c;一开始也是惨不忍睹&#xff0c;后来慢慢进入状态最近的面试基本都能走到终面&#xff0c;所以好好坚持&#xff0c;最后一定会有好结果的…

Pandas + ChatGPT 超强组合,pandas-ai :交互式数据分析和处理新方法

Python Pandas是一个为Python编程提供数据操作和分析功能的开源工具包。这个库已经成为数据科学家和分析师的必备工具。它提供了一种有效的方法来管理结构化数据(Series和DataFrame)。 在人工智能领域&#xff0c;Pandas经常用于机器学习和深度学习过程的预处理步骤。Pandas通过…