redis存储对象的过期设置在实际项目中的运用案例展示

redis存储对象的过期设置在实际项目中的运用案例展示!经过前面的学习,我们已经基本上初步掌握了redis数据库存储对象的过期时间是如何设置的了。下面给大家展示一个具体的实际开发项目中用到业务场景。


在项目化生寺小程序游戏开发中,有道具:鲜花,香,油灯;为了方便开发,把这这些道具统一规划到了一张表内:tb_pro;

但是,尽管如此,他们彼此之间还是存在一些差异的,比如鲜花会存在枯萎的情况,这个就是涉及到了有效期的问题。但是香火,和油灯则没有这个需求。我们在数据表内增加了一个字段:

如图,既然涉及到了有效期(过期)的业务需求,这个商品本身,必须具备一个唯一的键值,才能和别的商品区分开。


比如客户在2024-02-03 16:00:00分下单购买了一束鲜花(加入了客户自己的背包中了);那么,背包中的这束鲜花,就已经开始加入到了我们的redis数据库中了。此时它已经开启了有效期(过期的机制了)。我们设置的鲜花道具过期时间是,72小时候过期(枯萎)。

枯萎后的鲜花,是不能继续使用的。我们需要修改它的status(状态从正常-0;改成1-枯萎。)

虽然通常情况下,客户下单购买鲜花道具后,都是会马上进行消费(使用-上供供花属于消费行为。鲜花道具的状态会变成:2-已用)。

如上所示,我们mysql数据库用户背包内存储的鲜花道具的状态,是否发生变化,取决于2件事。

第一:用户的消费 行为,可以触发状态的改变。

第二:redis数据库内过期了。也会触发状态的改变。但是这种改变,是被动的,我们还没有使用消息通知的模式。只有当用户去使用的时候,我们才会去被动的判定,状态是不是已经枯萎了。

当然了,代码层面是可以完善的。借助于定时器。定一个间隔,轮询redis内的数据过期情况,查询到了过期,就给后端发送通知去修改状态。

这是后话。


我们使用了java官方自带的uuid来实现鲜花道具的唯一key。

 public static void main(String[] args) {
            String uniqueKey = UUID.randomUUID().toString();
            System.out.println("Unique Key: " + uniqueKey);
    }

 

它产生了一个字符串。

我们把它作为鲜花道具的唯一key。就可以在redis数据库内区别开了。


 

如图,在tb_bag数据表内,我们存储了所有用户的背包信息。

里面可以看见有user_id(哪个用户);key_no(哪个鲜花);pro_id(产品自身的id);pro_name(产品的名字);pro_count(产品的数量);pro_type_id(产品的分类id,0-鲜花,1-灯,2-香火);

实际上,对于不具备有效期的产品类型,我们无需给它生成唯一键。之所以我们需要一个唯一键,目的就是为了计算该产品的有效期。


@Data
@Entity
@Table(name = "tb_pro")
public class Product {
    @javax.persistence.Id
    @org.springframework.data.annotation.Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)//主键生成策略
    private Integer id;
    private String name;
    private Integer status;//状态:默认是0-正常,1-枯萎,2-已用
    private Integer life;//生命周期默认是72小时
    @Column(name = "life_end" ,nullable = true)
    private Integer lifeEnd;//生命周期结束值,初始为0
    private Integer price;//单价
    private Integer type;//产品种类:0-花,1-灯,2-香火
    private Integer source;//来源:默认是0-领取,1-购买,2-赠予
    @Column(name = "key_no",nullable = true)
    private String kyeNo;//唯一键.为了跟踪有效期

}

 如图,数据表对应的实体类。我们对不同的属性值和表内字段值进行了映射。


package com.yrl.managedemo.controller;

import com.yrl.managedemo.bean.Bag;
import com.yrl.managedemo.bean.Product;
import com.yrl.managedemo.bean.Result;
import com.yrl.managedemo.service.IBagService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/bag")
public class BagController {
    @Autowired
    private IBagService bagService;

    @GetMapping("/list")
    public Result<List<Bag>> getAllBag(){
        Result<List<Bag>> result = new Result<>();
        List<Bag> bagList = bagService.getAll();
        if(bagList.size()>0){
            result.setCode(200);
            result.setMsg("查询背包信息成功");
            result.setData(bagList);
            return  result;
        }else{
            result.setCode(500);
            result.setMsg("服务器异常");
            return  result;
        }
    }

    /**
     * 查询某一个用户的背包所有产品信息
     * @param id 用户id
     * @return
     */
    @GetMapping("/list/user")
    public Result<List<Bag>> getBagListByUserId(Integer id){
        Result<List<Bag>> result = new Result<>();
        List<Bag> userBagList = bagService.getBagListByUserId(id);
        if(userBagList.size()>0){
            result.setCode(200);
            result.setMsg("查询用户背包信息成功");
            result.setData(userBagList);
            return result;
        }else{
            result.setCode(500);
            result.setMsg("服务器异常");
            return  result;
        }
    }

    /**
     * 向背包中新增一条数据信息。
     * @param uid
     * @param product
     * @return
     */
    @PostMapping("/add")
    public Result addOneBagByUserId(Integer uid, Product product,Integer count){
        Result result = new Result();
        try{
            Bag bag = new Bag();
            //封装数据到对象中
            bag.setUserId(uid);
            bag.setKeyNo(product.getKyeNo());
            bag.setProCount(count);
            bag.setProId(product.getId());
            bag.setProName(product.getName());
            bag.setProTypeId(product.getType());
            bagService.addOneBag(bag);
            result.setCode(200);
            result.setMsg("新增一条背包信息成功");
            return result;
        }catch (Exception e){
            System.out.println(e.fillInStackTrace());
            result.setCode(500);
            result.setMsg("服务器异常");
            return  result;
        }


    }
}

如图是,背包控制器内的代码情况,

我们新增一条背包信息的时候,传递过来的产品信息是一个实体类的形式封装到了里面。里面已经有一个唯一key了。

它就是将来redis存储的时候,用了判定某个对象过期的关键所在。


/**
         * 设置某一个用户所拥有的某个产品的过期时间
         * @param uid 用户id
         * @param keyNo 产品的唯一键
         */
        @Test
        public void testAddFlower(Integer uid,String keyNo){
            Jedis  jedis= new Jedis("localhost",6379);
            //加入redis内部
            jedis.hset("keyNo","uid","uid");
            //设置过期时间 单位是秒。
            long endLife = 60*60*24*3;//72小时后过期。
            jedis.expire("keyNo",endLife);

        }

如图所示,我们设置了某一个用户,拥有的某一个产品的过期时间。

后期这个用户想使用这个产品时,会查询到,redis返回null.说明已经过期了.

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

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

相关文章

DC-7靶机渗透详细流程

信息收集&#xff1a; 1.存活扫描&#xff1a; 由于靶机和kali都是nat的网卡&#xff0c;都在一个网段&#xff0c;我们用arp-scan会快一点&#xff1a; arp-scan arp-scan -I eth0 -l └─# arp-scan -I eth0 -l Interface: eth0, type: EN10MB, MAC: 00:0c:29:dd:ee:6…

从零开始手写mmo游戏从框架到爆炸(十一)— 注册与登录

导航&#xff1a;从零开始手写mmo游戏从框架到爆炸&#xff08;零&#xff09;—— 导航-CSDN博客 从这一章开始&#xff0c;我们进入业务的部分&#xff0c;从注册登录开始。 创建注册和登录的路由 package com.loveprogrammer.command.server;public interface Se…

Java面向对象 继承

目录 继承继承的好处继承具有传递性实例创建Person类Student继承Person类测试 继承 Java中的继承是面向对象编程的一个核心特性&#xff0c;它允许一个类&#xff08;子类或派生类&#xff09;继承另一个类&#xff08;父类或基类&#xff09;的属性和方法。通过继承&#xff0…

蓝桥杯备战——12.超声波与测频代码优化

1.优化分析 昨天我在看原理图的发现超声波模块的反馈引脚P11刚好可以使用PCA模块0的捕获功能&#xff0c;我就想着把PCA功能留给超声波&#xff0c;然后测频功能还是改成定时器0来完成&#xff0c;然后前后台功能改成定时器1。 至于我为什么要这么改呢&#xff0c;看一下我原…

157基于matlab的GVF-snake算法能自动收敛到目标区域

基于matlab的GVF-snake算法能自动收敛到目标区域。关键技术GVF snake模型算法matlab源程序&#xff0c;GVF是根据光流场原理,利用变分方法,从图像中得到的一种向量场,该向量场被称为梯度矢量流(GVF)场。 Snake模型称为动态轮廓模型&#xff08;Active Contour Model&#xff0…

vue的8大生命周期

第072个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使用&#xff0c;computed&a…

51单片机之数码管显示表白数字篇

朝菌不知晦朔 蟪蛄不知春秋 眼界决定境界 CSDN 请求进入专栏 是否进入《51单片机专栏》? 确定 目录 数码管的简介 数码管引脚定义 数码管的原理图 74HC245 代码实现 静态数码管的显示 动态数码管的显示 数码管实现表白画面 数码管的简介 L…

阿里云ECS服务器Linux安装Mysql8

链接&#xff1a;https://pan.baidu.com/s/1s9j7OhiOMV9e9Qq9GDbysA 提取码&#xff1a;dd5a --来自百度网盘超级会员V5的分享 Mysql官网:MySQL 关于Mysql Yum Repository介绍可以看下 更加简单 关于X86和ARM 传到服务器 进入所在包 cd /usr/local/develop/mysql8 解压 …

深度学习(15)--PyTorch构建卷积神经网络

目录 一.PyTorch构建卷积神经网络(CNN)详细流程 二.graphviz torchviz使PyTorch网络可视化 2.1.可视化经典网络vgg16 2.2.可视化自己定义的网络 一.PyTorch构建卷积神经网络(CNN)详细流程 卷积神经网络&#xff08;Convolutional Neural Networks&#xff09;是一种深度学…

前端vite+vue3——自动化配置路由布局

文章目录 ⭐前言&#x1f496;vue3系列文章 ⭐ 自动化配置路由&#x1f496;引入vite版本自定义目录映射&#x1f496;自动化读取文件下的路由&#x1f496;main入口加载路由&#x1f496;入口app.vue配置&#x1f496;layout基础布局配置&#x1f496;效果 ⭐总结⭐结束 ⭐前言…

【MySQL进阶之路】BufferPool底层设计(上)

欢迎关注公众号&#xff08;通过文章导读关注&#xff1a;【11来了】&#xff09;&#xff0c;及时收到 AI 前沿项目工具及新技术的推送&#xff01; 在我后台回复 「资料」 可领取编程高频电子书&#xff01; 在我后台回复「面试」可领取硬核面试笔记&#xff01; 文章导读地址…

jvm垃圾收集器之七种武器

目录 1.回收算法 1.1 标记-清除算法(Mark-Sweep) 1.2 复制算法(Copying) 1.3 标记-整理算法(Mark-Compact) 2.HotSpot虚拟机的垃圾收集器 2.1 新生代的收集器 Serial 收集器&#xff08;复制算法&#xff09; ParNew 收集器 (复制算法) Parallel Scavenge 收集器 (复制…

OpenCV-32 膨胀操作

膨胀是与腐蚀相反的操作&#xff0c;基本原理是只要保证卷积核的锚点是非0值&#xff0c;周边无论是0还是非0值&#xff0c;都变为0。 使用API---dilate&#xff08;img&#xff0c; kernel&#xff0c; iterationms 1&#xff09; 示例代码如下&#xff1a; import cv2 imp…

C# 实现微信自定义分享

目录 需求与调整 代码实现 获取令牌 生成合法票据 获取有效签名 客户端准备 客户端实现 小结 需求与调整 在微信中打开网页应用后&#xff0c;可以选择将地址发送给朋友进行分享&#xff0c;如下图&#xff1a; 在实际的应用中&#xff0c;我们可能不是简单的将该网页…

HiveSQL——借助聚合函数与case when行转列

一、条件函数 if 条件函数 if函数是最常用到的条件函数&#xff0c;其写法是if(xn,a,b), xn代表判断条件&#xff0c;如果xn时&#xff0c;那么结果返回a ,否则返回b。 selectif(age < 25 or age is null, 25岁以下, 25岁以上) as age_cnt,count(1) as number from table…

搭建macOS开发环境-1:准备工作

请记住&#xff1a; 最重要的准备工作永远是&#xff1a;备份数据 !!! 通过图形界面检查 Mac 的 CPU 类型&#xff1a; 在搭载 Apple 芯片的 Mac 电脑上&#xff0c;“关于本机”会显示一个标有“芯片”的项目并跟有相应芯片的名称&#xff1a; 通过命令行检查Mac的CPU类型 …

java_error_in_pycharm.hprof文件是什么?能删除吗?

java_error_in_pycharm.hprof文件是什么&#xff1f;能删除吗&#xff1f; &#x1f335;文章目录&#x1f335; &#x1f333;引言&#x1f333;&#x1f333;hprof格式文件介绍&#x1f333;&#x1f333;java_error_in_pycharm.hprof文件什么情况下能删除&#x1f333;&…

Vue CLI学习笔记

在看任何开源库的源码之前&#xff0c;必须先了解它有哪些功能&#xff0c;这样才能针对性地分模块阅读源码。 Vue CLI 简介 Vue CLI是Vue.js的官方命令行工具&#xff0c;它是一个基于Vue.js进行快速开发的完整系统。 通过Vue CLI&#xff0c;开发者可以快速搭建和开发Vue.js项…

rsyslog远程记录系统日志

rsyslog是一个快速处理手机系统日志的开源程序&#xff0c;提供了高性能&#xff0c;安全功能和模块化设计&#xff0c;rsyslog是syslog的升级版&#xff0c;他讲多重来源输入输出转换结果到目的地&#xff0c;rsyslog被广泛用于Linux系统以通过TCP/UDP协议转发或接收日志消息。…

Gitlab和Jenkins集成 实现CI (一)

版本声明 部署时通过docker拉取的最新版本 gitlab: 16.8 jenkins: 2.426.3 安装环境 可参考这篇文章 停止防火墙 由于在内网&#xff0c;这里防火墙彻底关掉&#xff0c;如果再外网或者云上的悠着点 systemctl stop firewalled systemctl disable firewalledsystemctl sto…
最新文章