net6使用StackExchangeRedis实现分布式缓存

上一篇讲解了Redis的搭建及ServiceStack.Redis 与 StackExchange.Reids 的区别https://blog.csdn.net/qq_39569480/article/details/105249607

这篇文章遗我们来说下使用Microsoft.Extensions.Caching.StackExchangeRedis来对redis进行操作及帮助类。

首先在windows上安装redis 在上边连接中有教程 .

创建webapi项目
在这里插入图片描述

在包管理器中安装Microsoft.Extensions.Caching.StackExchangeRedis
在这里插入图片描述
在appsettings.json中添加连接字符串:(redis连接字符串)

  "ConnectionStrings": {
    "Redis": "123.123.33.22:6379,password=123456!,ConnectTimeout=15000,SyncTimeout=5000"
  },

定义一个接口

public interface ICache
{
    #region 设置缓存 
    /// <summary>
    /// 设置缓存
    /// </summary>
    /// <param name="key">缓存Key</param>
    /// <param name="value">值</param>
    void SetCache(string key, object value);
    /// <summary>
    /// 设置缓存
    /// </summary>
    /// <param name="key">缓存Key</param>
    /// <param name="value">值</param>
    Task SetCacheAsync(string key, object value);

    /// <summary>
    /// 设置缓存
    /// 注:默认过期类型为绝对过期
    /// </summary>
    /// <param name="key">缓存Key</param>
    /// <param name="value">值</param>
    /// <param name="minutes">过期时间间隔 以分钟为单位</param>
    void SetCache(string key, object value,int minutes);

    /// <summary>
    /// 设置缓存
    /// 注:默认过期类型为绝对过期
    /// </summary>
    /// <param name="key">缓存Key</param>
    /// <param name="value">值</param>
    /// <param name="timeout">过期时间间隔 以分钟为单位</param>
    Task SetCacheAsync(string key, object value, int minutes);

    /// <summary>
    /// 设置缓存
    /// 注:默认过期类型为绝对过期
    /// </summary>
    /// <param name="key">缓存Key</param>
    /// <param name="value">值</param>
    /// <param name="minutes">过期时间间隔 以分钟为单位</param>
    /// <param name="expireType">过期类型</param>  
    void SetCache(string key, object value, int minutes, ExpireType expireType);

    /// <summary>
    /// 设置缓存
    /// 注:默认过期类型为绝对过期
    /// </summary>
    /// <param name="key">缓存Key</param>
    /// <param name="value">值</param>
    /// <param name="minutes">过期时间间隔 以分钟为单位</param>
    /// <param name="expireType">过期类型</param>  
    Task SetCacheAsync(string key, object value, int minutes, ExpireType expireType);
    #endregion

    #region 获取缓存

    /// <summary>
    /// 获取缓存
    /// </summary>
    /// <param name="key">缓存Key</param>
    string GetCache(string key);

    /// <summary>
    /// 获取缓存
    /// </summary>
    /// <param name="key">缓存Key</param>
    Task<string> GetCacheAsync(string key);

    /// <summary>
    /// 获取缓存,没有则添加
    /// </summary>
    /// <param name="key"></param>
    /// <param name="value"></param>
    /// <param name="minutes"></param>
    /// <param name="expireType">过期类型,默认绝对过期</param>
    /// <returns></returns>
    Task<string> GetOrAddAsync(string key, object value, int minutes, ExpireType expireType = 0);
    /// <summary>
    /// 获取缓存
    /// </summary>
    /// <param name="key">缓存Key</param>
    T GetCache<T>(string key);
    /// <summary>
    /// 获取缓存
    /// </summary>
    /// <param name="key">缓存Key</param>
    Task<T> GetCacheAsync<T>(string key);

    /// <summary>
    /// 获取泛型缓存,没有则添加
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="key"></param>
    /// <param name="value"></param>
    /// <param name="minutes"></param>
    /// <param name="expireType">过期类型,默认绝对过期</param>
    /// <returns></returns>
    Task<T> GetOrAddAsync<T>(string key, object value, int minutes, ExpireType expireType = 0);

    #endregion

    #region 删除缓存

    /// <summary>
    /// 清除缓存
    /// </summary>
    /// <param name="key">缓存Key</param>
    void RemoveCache(string key);

    /// <summary>
    /// 清除缓存
    /// </summary>
    /// <param name="key">缓存Key</param>
    Task RemoveCacheAsync(string key);

    #endregion

    #region 刷新缓存
    /// <summary>
    /// 刷新缓存
    /// </summary>
    /// <param name="key">缓存Key</param>
    void RefreshCache(string key);
    /// <summary>
    /// 刷新缓存
    /// </summary>
    /// <param name="key">缓存Key</param>
    Task RefreshCacheAsync(string key);
    #endregion
}

实现接口中定义的方法

public class CacheHelper : ICache
{
    readonly IDistributedCache _cache;

    public CacheHelper(IDistributedCache cache)
    {
        _cache = cache;
    }

    protected string BuildKey(string idKey)
    {
        return $"Cache_{idKey}";
    }
    public void SetCache(string key, object value)
    {
        string cacheKey = BuildKey(key);
        _cache.SetString(cacheKey, value.ToJson());
    }

    public async Task SetCacheAsync(string key, object value)
    {
        string cacheKey = BuildKey(key);
        await _cache.SetStringAsync(cacheKey, value.ToJson());
    }

    public void SetCache(string key, object value,int minutes)
    {
        string cacheKey = BuildKey(key);
        _cache.SetString(cacheKey, value.ToJson(), new DistributedCacheEntryOptions
        {
            AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(minutes)
        });
    }

    public async Task SetCacheAsync(string key, object value, int minutes)
    {
        string cacheKey = BuildKey(key);
        await _cache.SetStringAsync(cacheKey, value.ToJson(), new DistributedCacheEntryOptions
        {
            AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(minutes)
        });
    }

    public void SetCache(string key, object value, int minutes, ExpireType expireType)
    {
        string cacheKey = BuildKey(key);
        if (expireType == ExpireType.Absolute)
        {
            //这里没转换标准时间,Linux时区会有问题?
            _cache.SetString(cacheKey, value.ToJson(), new DistributedCacheEntryOptions
            {
                AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(minutes)
            });
        }
        else
        {
            _cache.SetString(cacheKey, value.ToJson(), new DistributedCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(minutes)
            });
        }
    }

    public async Task SetCacheAsync(string key, object value, int minutes, ExpireType expireType)
    {
        string cacheKey = BuildKey(key);
        if (expireType == ExpireType.Absolute)
        {
            //这里没转换标准时间,Linux时区会有问题?
            await _cache.SetStringAsync(cacheKey, value.ToJson(), new DistributedCacheEntryOptions
            {
                AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(minutes)
            });
        }
        else
        {
            await _cache.SetStringAsync(cacheKey, value.ToJson(), new DistributedCacheEntryOptions
            {
                AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(minutes)
            });
        }
    }

    public string GetCache(string idKey)
    {
        if (idKey.IsNullOrEmpty())
        {
            return null;
        }
        string cacheKey = BuildKey(idKey);
        var cache = _cache.GetString(cacheKey);
        return cache;
    }
    public async Task<string> GetCacheAsync(string key)
    {
        if (key.IsNullOrEmpty())
        {
            return null;
        }
        string cacheKey = BuildKey(key);
        var cache = await _cache.GetStringAsync(cacheKey);
        return cache;
    }
    public async Task<string> GetOrAddAsync(string key,object value,int minutes, ExpireType expireType=0)
    {
        if (key.IsNullOrEmpty()) return null;

        string cacheKey = BuildKey(key);
        var cache = await _cache.GetStringAsync(cacheKey);
        if (cache==null&& value!=null)
        {
            string json= value.ToJson();
            if (expireType == ExpireType.Absolute)
            {
                //这里没转换标准时间,Linux时区会有问题?
                await _cache.SetStringAsync(cacheKey, json, new DistributedCacheEntryOptions
                {
                    AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(minutes)
                });
            }
            else
            {
                await _cache.SetStringAsync(cacheKey, json, new DistributedCacheEntryOptions
                {
                    AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(minutes)
                });
            }
            return json;
        }
        return cache;
    }

    public T GetCache<T>(string key)
    {
        var cache = GetCache(key);
        if (!cache.IsNullOrEmpty())
        {
            return cache.ToObject<T>();
        }
        return default(T);
    }

    public async Task<T> GetCacheAsync<T>(string key)
    {
        var cache = await GetCacheAsync(key);
        if (!string.IsNullOrEmpty(cache))
        {
            return cache.ToObject<T>();
        }
        return default(T);
    }
    public async Task<T> GetOrAddAsync<T>(string key, object value, int minutes, ExpireType expireType = 0)
    {
        if (key.IsNullOrEmpty()) return default(T);

        string cacheKey = BuildKey(key);
        var cache = await _cache.GetStringAsync(cacheKey);
        if (cache == null && value != null)
        {
            string json = value.ToJson();
            if (expireType == ExpireType.Absolute)
            {
                //这里没转换标准时间,Linux时区会有问题?
                await _cache.SetStringAsync(cacheKey, json, new DistributedCacheEntryOptions
                {
                    AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(minutes)
                });
            }
            else
            {
                await _cache.SetStringAsync(cacheKey, json, new DistributedCacheEntryOptions
                {
                    AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(minutes)
                });
            }
            return json.ToObject<T>();
        }
        return cache.ToObject<T>();
    }

    public void RemoveCache(string key)
    {
        _cache.Remove(BuildKey(key));
    }

    public async Task RemoveCacheAsync(string key)
    {
        await _cache.RemoveAsync(BuildKey(key));
    }

    public void RefreshCache(string key)
    {
        _cache.Refresh(BuildKey(key));
    }

    public async Task RefreshCacheAsync(string key)
    {
        await _cache.RefreshAsync(BuildKey(key));
    }
}

定义一个枚举的过期类型

public enum ExpireType
{
    /// <summary>
    /// 绝对过期
    /// 注:即自创建一段时间后就过期
    /// </summary>
    Absolute,

    /// <summary>
    /// 相对过期
    /// 注:即该键未被访问后一段时间后过期,若此键一直被访问则过期时间自动延长
    /// </summary>
    Relative,
}

定义一个string的扩展方法

public static class ValueToObject
{
    /// <summary>
    /// 将Json字符串反序列化为对象
    /// </summary>
    /// <typeparam name="T">对象类型</typeparam>
    /// <param name="jsonStr">Json字符串</param>
    /// <returns></returns>
    public static T ToObject<T>(this string jsonStr)
    {
        return JsonConvert.DeserializeObject<T>(jsonStr);
    }
    /// <summary>
    /// 将字符串序列化为json
    /// </summary>
    /// <param name="str"></param>
    /// <returns></returns>
    public static string ToJson(this object str)
    {
        return JsonConvert.SerializeObject(str);
    }
}

在Program.cs文件中注入并添加redis

builder.Services.AddScoped(typeof(ICache), typeof(CacheHelper));//注入

builder.Services.AddStackExchangeRedisCache(o =>
{
    //redis连接
    o.Configuration = builder.Configuration.GetConnectionString("Redis");
    //设置缓存key的前缀
    //o.InstanceName = "";
});

控制器中使用

[Route("demo")]
[ApiController]
//[Authorize]
public class DemoController : ControllerBase
{
    private readonly IDemoService _demo;
    public DemoController(IDemoService demo)
    {
        _demo = demo;
    }

    /// <summary>
    /// 获取列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    public async Task<dynamic> Get(int id)
    {
         DemoGetOutPut demo=await _cache.GetOrAddAsync<DemoGetOutPut>($"demo{id}", async () => await GetDemo(id),20);
        return demo;
    }
    
    public async Task<dynamic> Get(int id)
    {
        return new { name= "张三", age= 18 };
    }
}

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

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

相关文章

【一】FPGA实现SPI协议之SPI协议介绍

【一】FPGA实现SPI协议之SPI协议介绍 一、spi协议解析 spi协议有4根线&#xff0c;主机输出从机输入MOSI、主机输入从机输出MISO、时钟信号SCLK、片选信号SS\CS 。 一般用于主机和从机之间通信。由主机发起读请求和写请求&#xff0c;主机的权限是主动的&#xff0c;从机是被…

STM32——串口通信应用篇

一、引言 STM32微控制器是一款功能强大的嵌入式系统芯片&#xff0c;广泛应用于各种领域。其中&#xff0c;串口通信是其重要功能之一&#xff0c;可用于与外部设备进行数据交换和控制。本文将介绍STM32串口通信的基本原理、应用场景以及实现方法。 二、STM32串口通信基本原理 …

Ubuntu 虚拟机环境,编译AOSP源码

环境 : VMware虚拟机 Ubuntu 20.04.3 LTS 搭建配置开发环境 sudo apt-get install git-core gnupg flex bison build-essential zip curl zlib1g-dev gcc-multilib g-multilib libc6-dev-i386 libncurses5 lib32ncurses5-dev x11proto-core-dev libx11-dev lib32z1-dev libgl…

【大数据存储与处理】实验一 HBase 的基本操作

一、实验目的&#xff1a; 1. 掌握 Hbase 创建数据库表及删除数据库表 2. 掌握 Hbase 对数据库表数据的增、删、改、查。 二、实验内容&#xff1a; 1、题目 0&#xff1a;进入 hbase shell 2、题目 1&#xff1a;Hbase 创建数据库表 创建数据库表的命令&#xff1a;create 表…

CW32单片机在智能马桶的应用介绍

智能科技的迅速发展使得我们的日常生活变得更加便捷和舒适。智能马桶作为其中一种智能家居产品&#xff0c;通过单片机接受和处理来自传感器的数据&#xff0c;然后通过控制模块对智能马桶的各项功能进行控制&#xff0c;实现对智能马桶的全面控制和调节。本文将介绍CW32单片机…

【SSM】MyBatis

MyBatis 文章目录 MyBatis1. 简介2. 使用流程3. 基本使用3.1 配置文件3.2 SQL语句传参3.2 数据输入3.2.1 单个简单类型参数3.2.2 多个简单类型数据3.2.3 实体类类型参数3.2.4 Map类型参数 3.3 数据输出3.3.1 resultType指定输出类型3.3.2 返回实体类对象注意点3.3.3 返回主键值…

【PostgreSQL内核学习(十八)—— 存储管理(存储管理的体系结构)】

存储管理 概述存储管理器的体系结构存储管理器的主要任务读写元组过程 声明&#xff1a;本文的部分内容参考了他人的文章。在编写过程中&#xff0c;我们尊重他人的知识产权和学术成果&#xff0c;力求遵循合理使用原则&#xff0c;并在适用的情况下注明引用来源。 本文主要参考…

基于C语言的坦克大战游戏开发

基于C语言的坦克大战游戏开发 在这篇文章中,我们将介绍如何使用C语言编写一个基本的坦克大战游戏。我们将使用C语言的基本语法和数据结构来实现游戏的逻辑和功能。 一、游戏概述 坦克大战是一款经典的射击游戏,玩家需要控制坦克在战场上移动、射击敌人并摧毁它们。游戏中…

MongoDB的查询分析explain和hint

本文主要介绍MongoDB的查询分析explain和hint。 目录 MongoDB的查询分析explainhint MongoDB的查询分析 在MongoDB中&#xff0c;"explain"和"hint"是两个用于查询优化和分析的关键指令。 explain 在MongoDB中&#xff0c;explain()是一个用于查询分析的…

【Java】学习指南总结(少走弯路必看!)

开篇 作为初学者&#xff0c;接触Java可能会觉得有些复杂。本文旨在帮助大家轻松入门Java&#xff0c;避免走弯路。 基础理解 刚开始接触Java时&#xff0c;首要任务是理解Java的基本构成。这包括Java的基础语法、应用范围、以及Java的核心组成部分&#xff1a;JVM&#xf…

CentOs7.x安装部署SeaTunnelWeb遇到的坑

CentOs7.x安装部署SeaTunnelWeb遇到的坑 文章目录 1. 环境2. SeaTunnel安装部署2.1下载安装包2.2 设置环境变量2.3 安装连接器插件2.4 拷贝jar包到lib下2.5 启动命令2.6 执行官方client提交任务demo 3. SeaTunnel-Web安装部署3.1 下载安装包3.2 初始化数据库脚本或修改配置appl…

【可用性】Redis作为注册中心配合Spring Task的高可用案例

需求&#xff1a; 假设当前有一个短信服务是多节点集群部署&#xff0c;我们希望每个服务节点在启动时能将服务信息"注册"到redis缓存中&#xff0c;所有服务节点每隔3分钟上报一次&#xff0c;表示当前服务可用。每个服务还会作为哨兵节点每隔10分钟查询一次redis&a…

STM32-I2C通讯-AHT20温湿度检测

非常感谢&#xff0c;提供的视频学习 https://www.bilibili.com/video/BV1QN411D7ak/?spm_id_from333.788&vd_source8ca4826038edd44bb618801808a5e076 该文章注意&#xff1a;串口显示中文会乱码&#xff0c;必须选用支持ASCII的串口助手&#xff0c;才能正常显示中文。…

针对这两个趋势,3.0全新新零售商业模式可以采取以下策略:

国内市场确实存在“消费升级”和“消费降级”两个趋势&#xff0c;这是由于不同消费者群体的需求和购买力存在差异。消费升级主要发生在高端市场&#xff0c;消费者愿意为高品质、高价值、高价格的商品和服务付出更多。而消费降级则主要发生在中低端市场&#xff0c;消费者更加…

ROS学习笔记(七)---参数服务器

ROS学习笔记文章目录 01. ROS学习笔记(一)—Linux安装VScode 02. ROS学习笔记(二)—使用 VScode 开发 ROS 的Python程序&#xff08;简例&#xff09; 03. ROS学习笔记(三)—好用的终端Terminator 04. ROS学习笔记(四)—使用 VScode 启动launch文件运行多个节点 05. ROS学习笔…

Golang(壹)

爱情不需要华丽的言语&#xff0c;只需要默默的行动。 简介 应用领域&#xff1a; 下载vscode 使用vscode Go下载 - Go语言中文网 - Golang中文社区 下载sdk 解压到文件中&#xff0c;打开sdk解压文件 穿插dos操作系统知识点&#xff1a; 测试go语言环境 看到vscode 的目录结…

Redis学习笔记(二)

1. 说一说Redis集群的应用和优劣势 参考答案 优势&#xff1a; Redis Cluster是Redis的分布式解决方案&#xff0c;在3.0版本正式推出&#xff0c;有效地解决了Redis分布式方面的需求。当遇到单机内存、并发、流量等瓶颈时&#xff0c;可以采用Cluster架构方案达到负载均衡的…

智能优化算法应用:基于闪电连接过程算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于闪电连接过程算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于闪电连接过程算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.闪电连接过程算法4.实验参数设定…

Idea远程debugger调试

当我们服务部署在服务器上&#xff0c;我们想要像在本地一样debug,就可以使用idea自带的Remote JVM Debug 创建Remote JVM Debug服务器启动jar打断点进入断点 当我们服务部署在服务器上&#xff0c;我们想要像在本地一样debug,就可以使用idea自带的 Remote JVM Debug) 创建Rem…

UE5 水材质注意要点

1、两个法线反向交替流动&#xff0c;可以去观感假的现象 2、水面延边的透明度低 3、增加水面延边的浪花 4、增加折射 折射要整体质量至少在High才有效果 改为半透明材质没有法线信息&#xff1f; 5、处理反射效果 勾选为true 找到这个放在水域 勾为false&#xff0c;即可有非…
最新文章