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

news2024/11/14 23:41:51

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.coloradmin.cn/o/1429781.html

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

相关文章

什么是TCP粘包和半包问题?如何解决?

什么是TCP粘包问题&#xff1f;如何解决&#xff1f; TCP粘包和半包是数据传输中比较常见的问题。所谓的粘包问题就是指在数据传输的时候&#xff0c;在一条消息中读取到了另一条消息的部分数据&#xff0c;如下图&#xff1a; 半包是指接收端只收到了部分的数据&#xff0c;而…

【C语言/基础梳理/期末复习】动态内存管理(附思维导图)

目录 一、为什么要有动态内存分配 &#xff08;1&#xff09;我们已经掌握的内存方式的特点 &#xff08;2&#xff09;需求 二、malloc和free 2.1.malloc 2.1.1函数原型 2.1.2函数使用 2.1.3应用示例​编辑 2.2free 2.2.1函数原型 2.2.2函数使用 三、calloc和reallo…

算法练习-左叶子之和(思路+流程图+代码)

难度参考 难度&#xff1a;中等 分类&#xff1a;二叉树 难度与分类由我所参与的培训课程提供&#xff0c;但需要注意的是&#xff0c;难度与分类仅供参考。且所在课程未提供测试平台&#xff0c;故实现代码主要为自行测试的那种&#xff0c;以下内容均为个人笔记&#xff0c;旨…

rust gui开发框架选择

作为一个系统编程强大语言&#xff0c;怎么能少得了图形界面的开发 实际上写这篇前我也不知道&#xff0c;于是我问了ai大模型&#xff0c;文心3.5和chatgpt4.0 答案实际上不能满意&#xff0c;最后我做了下筛选 参考博文&#xff1a; rust开发环境配置&#xff1a;链接 一、…

Loadbalancer如何优雅分担服务负荷

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 Loadbalancer如何优雅分担服务负荷 前言Loadbalancer基础&#xff1a;数字世界的分配大师1. 分发请求&#xff1a;2. 健康检查&#xff1a;3. 会话保持&#xff1a;4. 可伸缩性&#xff1a;5. 负载均衡…

数据结构—基础知识:哈夫曼编码

文章目录 数据结构—基础知识&#xff1a;哈夫曼编码哈夫曼编码的主要思想有关编码的概念哈夫曼编码满足两个性质&#xff1a; 数据结构—基础知识&#xff1a;哈夫曼编码 哈夫曼编码的主要思想 在进行数据压缩时&#xff0c;为了使压缩后的数据文件尽可能短&#xff0c;可采…

二手电脑配置给你不一样的成就感

回顾从小到大使用电脑、组装电脑到开发软硬件的经历&#xff0c;总是对二手电脑有着不一样的情感&#xff0c;近五年买过八台新电脑&#xff0c;一台是图像处理培训买的笔记本&#xff0c;一台是小孩上课的台式机&#xff0c;一台是老人的集成办卡电脑&#xff0c;还有一些工作…

Vue3_基础使用_2

这节主要介绍&#xff1a;标签和组件的ref属性&#xff0c;父子组件间的传递值&#xff0c;ts的接口定义&#xff0c;vue3的生命周期 1.标签的ref属性。 1.1ref属性就是给标签打标识用的&#xff0c;相当于html的id&#xff0c;但是在vue3中用id可能会乱&#xff0c;下面是ref…

跟着cherno手搓游戏引擎【18】抽象Shader、项目小修改

抽象&#xff1a; Shader.h: #pragma once #include <string>namespace YOTO {class Shader {public:virtual~Shader()default;virtual void Bind()const0;virtual void UnBind()const0;static Shader* Create(const std::string& vertexSrc, const std::string&am…

软考高项-机考相关介绍论文写作基础介绍

机考相关 初、中级(信息处理技术员除外)资格:基础知识和应用技术2个科目连考,基础知识科目最短作答时长90分钟,最长作答时长120分钟,2个科目作答总时长240分钟,考试结束前60分钟可交卷离场 历年论文考题

java数据结构与算法刷题-----LeetCode15. 三数之和

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 解题思路 和LeetCode1.两数之和一样&#xff0c;但是这道题边界条件更多。…

Flutter 各种Demo效果合集

Flutter 各种Demo实现效果&#xff1a; github&#xff1a;GitHub - PangHaHa12138/FlutterDemo: Flutter 各种Demo效果合集 1&#xff1a;2种 仿朋友圈 效果,顶部拉伸 和 不拉伸 2&#xff1a;仿抖音上下滑动视频播放 3&#xff1a;视频直播&#xff08;使用的电视台的m3u…

云计算基础(云计算概述)

目录 一、云计算概述 1.1 云计算的概念 1.1.1 云计算解决的问题 1.1.2 云计算的概念 1.1.3 云计算的组成 1.2 云计算主要特征 1.2.1 按需自助服务 1.2.2 泛在接入 1.2.3 资源池化 1.2.4 快速伸缩性 1.2.5 服务可度量 1.3 云计算服务模式 1.3.1 软件即服务(Softwar…

C#验证字符串是否包含汉字:用正则表达式 vs 用ASCII码 vs 用汉字的 Unicode 编码

目录 一、使用的方法 1.使用正则表达式验证字符串 2.使用正则表达式验证字符 3.用ASCII码判断 4.用汉字的 Unicode 编码范围判断 二、实例 1.源码 2.生成效果 验证一个字符串是否是纯汉字或者包含有汉字的前提&#xff0c;是VS编辑器的默认编码格式设置为&#xff1a;选…

Vite与Webpack打包内存溢出问题优雅处理方式

Vite与Webpack打包内存溢出问题处理 文章目录 Vite与Webpack打包内存溢出问题处理1. Vite1. 打包错误提示2. 命令行方式解决3. 配置环境变量方式解决1. 设置变量2. 配置系统的环境变量 2. Webpack1. 打包错误提示2. 命令行方式解决3. 配置环境变量方式解决1. 设置变量2. 配置系…

Llama2大模型开源,大模型的Android时代来了?

就昨天凌晨,微软和Meta宣布Llama2大模型开源且进一步放开商用,一下朋友圈刷屏。要知道,开源界最强大的模型就是过去Meta开源的Llama,而现在Llama2更强大,又开放商用,更有微软大模型霸主企业撑腰(微软既投资大模型界的IOS——ChatGPT,又联合发布大模型的Android——Llam…

旧衣物回收小程序开发,互联网模式下的营收有多大?

在当下快节奏的生活中&#xff0c;人们不仅生活水平在提高&#xff0c;消费水平也在逐渐提高&#xff0c;从而导致了闲置衣物的增加。为了减少浪费&#xff0c;旧衣服回收行业受到了大众的广泛关注&#xff0c;成为循环利用的一大方式。 当然&#xff0c;在当下网络时代&#…

Docker 阿里云镜像仓库CR使用实践

一、使用容器镜像&#xff0c;查看镜像&#xff0c;创建&#xff0c;推送&#xff0c;拉取阿里云镜像 CR镜像管理&#xff08;阿里云容器镜像服务&#xff08;Container Registry&#xff09;&#xff09; 登录实例 未创建的镜像名称也可以push、docker的私有仓库需要提起创建…

C语言——深入理解指针(1)

目录 1.内存和地址 a 内存的理解 b 如何理解编址 2.指针变量和地址 a 取地址操作符 b 指针变量 c 解引用操作符 d 指针变量的大小 1.内存和地址 a 内存的理解 假想这样一个场景&#xff0c;你的朋友找你玩&#xff0c;到了你家小区&#xff0c;如何让她迅速的找到…

时间复杂度为 O(n) 的排序算法

大家好&#xff0c;我是 方圆。本文介绍线性排序&#xff0c;即时间复杂度为 O(n) 的排序算法&#xff0c;包括桶排序&#xff0c;计数排序和基数排序&#xff0c;它们都不是基于比较的排序算法&#xff0c;大家重点关注一下这些算法的适用场景。 桶排序 桶排序是分治策略的一…