Asp.Net Core基于StackExchange Redis 缓存
NuGet安装
StackExchange.Redis
Microsoft.Extensions.Options
0. appsettings.json初始化配置
{"Logging": {"LogLevel": {"Default": "Information","Microsoft.AspNetCore": "Warning"}},"AllowedHosts": "*","Redis": {"ConnectionString": "localhost:6379","InstanceName": "anna_","DefaultDatabase": 5,"ConnectRetry": 3,"ConnectTimeout": 5000,"AbortOnConnectFail": false},"ConnectionStrings": {"default": "Host=10.10.11.185;Port=5432;Database=KSJGOM2DB;Username=postgres;Password=money13;"}
}
1.Redis初始化对象
/// <summary>
/// Redis初始化对象
/// </summary>
public class RedisOptions
{public const string Redis = "Redis";public string ConnectionString { get; set; }public string InstanceName { get; set; }public int DefaultDatabase { get; set; } = 0;public int ConnectRetry { get; set; } = 3;public int ConnectTimeout { get; set; } = 5000;public bool AbortOnConnectFail { get; set; } = false;
}
2.接口
public interface IRedisService
{#region String 操作Task<bool> StringSetAsync<T>(string key, T value, TimeSpan? expiry = null);Task<T> StringGetAsync<T>(string key);Task<long> StringIncrementAsync(string key, long value = 1);Task<long> StringDecrementAsync(string key, long value = 1);#endregion#region Hash 操作Task<bool> HashSetAsync<T>(string hashKey, string key, T value);Task<bool> HashDeleteAsync(string hashKey, string key);Task<T> HashGetAsync<T>(string hashKey, string key);Task<Dictionary<string, T>> HashGetAllAsync<T>(string hashKey);Task<long> HashLengthAsync(string hashKey);#endregion#region List 操作Task<long> ListLeftPushAsync<T>(string key, T value);Task<long> ListRightPushAsync<T>(string key, T value);Task<T> ListLeftPopAsync<T>(string key);Task<T> ListRightPopAsync<T>(string key);Task<long> ListLengthAsync(string key);Task<IEnumerable<T>> ListRangeAsync<T>(string key, long start = 0, long stop = -1);#endregion#region Set 操作Task<bool> SetAddAsync<T>(string key, T value);Task<bool> SetRemoveAsync<T>(string key, T value);Task<bool> SetContainsAsync<T>(string key, T value);Task<long> SetLengthAsync(string key);Task<IEnumerable<T>> SetMembersAsync<T>(string key);#endregion#region SortedSet 操作Task<bool> SortedSetAddAsync<T>(string key, T value, double score);Task<bool> SortedSetRemoveAsync<T>(string key, T value);Task<double?> SortedSetScoreAsync<T>(string key, T value);Task<long> SortedSetLengthAsync(string key);Task<IEnumerable<T>> SortedSetRangeByRankAsync<T>(string key, long start = 0, long stop = -1, Order order = Order.Ascending);Task<IEnumerable<T>> SortedSetRangeByScoreAsync<T>(string key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Order order = Order.Ascending);#endregion#region 通用操作Task<bool> KeyDeleteAsync(string key);Task<bool> KeyExistsAsync(string key);Task<bool> KeyExpireAsync(string key, TimeSpan? expiry);Task<TimeSpan?> KeyTimeToLiveAsync(string key);#endregion
}
3. 实现
public class RedisService : IRedisService, IDisposable
{private readonly IConnectionMultiplexer _redis;private readonly RedisOptions _options;private readonly IDatabase _database;private readonly JsonSerializerOptions _jsonOptions;public RedisService(IOptions<RedisOptions> optionsAccessor){_options = optionsAccessor.Value;_jsonOptions = new JsonSerializerOptions{PropertyNamingPolicy = JsonNamingPolicy.CamelCase,WriteIndented = false};var config = ConfigurationOptions.Parse(_options.ConnectionString);config.AbortOnConnectFail = _options.AbortOnConnectFail;config.ConnectRetry = _options.ConnectRetry;config.ConnectTimeout = _options.ConnectTimeout;_redis = ConnectionMultiplexer.Connect(config);_database = _redis.GetDatabase(_options.DefaultDatabase);}private string GetPrefixedKey(string key) => $"{_options.InstanceName}{key}";#region String 操作实现public async Task<bool> StringSetAsync<T>(string key, T value, TimeSpan? expiry = null){var json = JsonSerializer.Serialize(value, _jsonOptions);return await _database.StringSetAsync(GetPrefixedKey(key), json, expiry);}public async Task<T> StringGetAsync<T>(string key){var value = await _database.StringGetAsync(GetPrefixedKey(key));return value.HasValue ? JsonSerializer.Deserialize<T>(value, _jsonOptions) : default;}public async Task<long> StringIncrementAsync(string key, long value = 1){return await _database.StringIncrementAsync(GetPrefixedKey(key), value);}public async Task<long> StringDecrementAsync(string key, long value = 1){return await _database.StringDecrementAsync(GetPrefixedKey(key), value);}#endregion#region Hash 操作实现public async Task<bool> HashSetAsync<T>(string hashKey, string key, T value){var json = JsonSerializer.Serialize(value, _jsonOptions);return await _database.HashSetAsync(GetPrefixedKey(hashKey), key, json);}public async Task<bool> HashDeleteAsync(string hashKey, string key){return await _database.HashDeleteAsync(GetPrefixedKey(hashKey), key);}public async Task<T> HashGetAsync<T>(string hashKey, string key){var value = await _database.HashGetAsync(GetPrefixedKey(hashKey), key);return value.HasValue ? JsonSerializer.Deserialize<T>(value, _jsonOptions) : default;}public async Task<Dictionary<string, T>> HashGetAllAsync<T>(string hashKey){var entries = await _database.HashGetAllAsync(GetPrefixedKey(hashKey));return entries.ToDictionary(x => x.Name.ToString(),x => JsonSerializer.Deserialize<T>(x.Value, _jsonOptions));}public async Task<long> HashLengthAsync(string hashKey){return await _database.HashLengthAsync(GetPrefixedKey(hashKey));}#endregion#region List 操作实现public async Task<long> ListLeftPushAsync<T>(string key, T value){var json = JsonSerializer.Serialize(value, _jsonOptions);return await _database.ListLeftPushAsync(GetPrefixedKey(key), json);}public async Task<long> ListRightPushAsync<T>(string key, T value){var json = JsonSerializer.Serialize(value, _jsonOptions);return await _database.ListRightPushAsync(GetPrefixedKey(key), json);}public async Task<T> ListLeftPopAsync<T>(string key){var value = await _database.ListLeftPopAsync(GetPrefixedKey(key));return value.HasValue ? JsonSerializer.Deserialize<T>(value, _jsonOptions) : default;}public async Task<T> ListRightPopAsync<T>(string key){var value = await _database.ListRightPopAsync(GetPrefixedKey(key));return value.HasValue ? JsonSerializer.Deserialize<T>(value, _jsonOptions) : default;}public async Task<long> ListLengthAsync(string key){return await _database.ListLengthAsync(GetPrefixedKey(key));}public async Task<IEnumerable<T>> ListRangeAsync<T>(string key, long start = 0, long stop = -1){var values = await _database.ListRangeAsync(GetPrefixedKey(key), start, stop);return values.Select(v => JsonSerializer.Deserialize<T>(v, _jsonOptions));}#endregion#region Set 操作实现public async Task<bool> SetAddAsync<T>(string key, T value){var json = JsonSerializer.Serialize(value, _jsonOptions);return await _database.SetAddAsync(GetPrefixedKey(key), json);}public async Task<bool> SetRemoveAsync<T>(string key, T value){var json = JsonSerializer.Serialize(value, _jsonOptions);return await _database.SetRemoveAsync(GetPrefixedKey(key), json);}public async Task<bool> SetContainsAsync<T>(string key, T value){var json = JsonSerializer.Serialize(value, _jsonOptions);return await _database.SetContainsAsync(GetPrefixedKey(key), json);}public async Task<long> SetLengthAsync(string key){return await _database.SetLengthAsync(GetPrefixedKey(key));}public async Task<IEnumerable<T>> SetMembersAsync<T>(string key){var values = await _database.SetMembersAsync(GetPrefixedKey(key));return values.Select(v => JsonSerializer.Deserialize<T>(v, _jsonOptions));}#endregion#region SortedSet 操作实现public async Task<bool> SortedSetAddAsync<T>(string key, T value, double score){var json = JsonSerializer.Serialize(value, _jsonOptions);return await _database.SortedSetAddAsync(GetPrefixedKey(key), json, score);}public async Task<bool> SortedSetRemoveAsync<T>(string key, T value){var json = JsonSerializer.Serialize(value, _jsonOptions);return await _database.SortedSetRemoveAsync(GetPrefixedKey(key), json);}public async Task<double?> SortedSetScoreAsync<T>(string key, T value){var json = JsonSerializer.Serialize(value, _jsonOptions);return await _database.SortedSetScoreAsync(GetPrefixedKey(key), json);}public async Task<long> SortedSetLengthAsync(string key){return await _database.SortedSetLengthAsync(GetPrefixedKey(key));}public async Task<IEnumerable<T>> SortedSetRangeByRankAsync<T>(string key, long start = 0, long stop = -1, Order order = Order.Ascending){var values = await _database.SortedSetRangeByRankAsync(GetPrefixedKey(key), start, stop, order);return values.Select(v => JsonSerializer.Deserialize<T>(v, _jsonOptions));}public async Task<IEnumerable<T>> SortedSetRangeByScoreAsync<T>(string key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Order order = Order.Ascending){var values = await _database.SortedSetRangeByScoreAsync(GetPrefixedKey(key), start, stop, order: order);return values.Select(v => JsonSerializer.Deserialize<T>(v, _jsonOptions));}#endregion#region 通用操作实现public async Task<bool> KeyDeleteAsync(string key){return await _database.KeyDeleteAsync(GetPrefixedKey(key));}public async Task<bool> KeyExistsAsync(string key){return await _database.KeyExistsAsync(GetPrefixedKey(key));}public async Task<bool> KeyExpireAsync(string key, TimeSpan? expiry){return await _database.KeyExpireAsync(GetPrefixedKey(key), expiry);}public async Task<TimeSpan?> KeyTimeToLiveAsync(string key){return await _database.KeyTimeToLiveAsync(GetPrefixedKey(key));}#endregionpublic void Dispose(){_redis?.Dispose();}
}
4.依赖注入
Program.cs中添加如下代码:
// 配置Redis选项builder.Services.Configure<RedisOptions>(builder.Configuration.GetSection(RedisOptions.Redis));// 注册Redis服务builder.Services.AddSingleton<IRedisService, RedisService>();
5.控制器中使用
public class TestController : ControllerBase
{private readonly IRedisService _redis;private readonly IUserService _userService;public TestController(IRedisService redis, IUserService userService) {_redis = redis;_userService = userService;}[HttpGet("string")]public async Task<IActionResult> TestString(){var user = await _userService.GetCurrentUserAsync();Console.WriteLine(user.TrueName);await _redis.StringSetAsync("anna","多慢慢流");var result = await _redis.StringGetAsync<string>("anna");return Ok(result);}[HttpGet("hash")]public async Task<IActionResult> TestHash(){string hkey = "fdm";await _redis.HashSetAsync(hkey, "fd1",new {Name="annadeville",Props="运动型" });await _redis.HashSetAsync(hkey,"fd2",new { Name="RR",Props="皮"});var all= await _redis.HashGetAllAsync<dynamic>(hkey);var fd1 = await _redis.HashGetAsync<dynamic>(hkey, "fd1");return Ok(new { All = all, Field1 = fd1 });}}
相关文章:
Asp.Net Core基于StackExchange Redis 缓存
NuGet安装 StackExchange.Redis Microsoft.Extensions.Options 0. appsettings.json初始化配置 {"Logging": {"LogLevel": {"Default": "Information","Microsoft.AspNetCore": "Warning"}},"AllowedHos…...
【Linux】SSH:免密登录
配置 SSH 的免密登录(基于公钥认证)可实现无需输入密码即可登录远程主机,常用于自动化脚本、服务器集群、DevOps 等场景。 生成本地 SSH 密钥对(若尚未存在) 在本地客户端执行: ssh-keygen -t rsa -b 409…...

kafka(windows)
目录 介绍 下载 配置 测试 介绍 Kafka是一个分布式流媒体平台,类似于消息队列或企业信息传递系统。 下载 Kafka对于Zookeeper是强依赖,所以安装Kafka之前必须先安装zookeeper 官网:Apache Kafka 下载此安装包并解压 配置 新建log…...
深度学习习题3
1.训练神经网络过程中,损失函数在一些时期(Epoch)不再减小, 原因可能是: 1.学习率太低 2.正则参数太大 3.卡在了局部最小值 A1 and 2 B. 2 and 3 C. 1 and 3 D. 都是 2.对于分类任务,我们不是将神经网络中的随机权重…...
勒让德多项式
勒让德多项式 (Legendre) 当区间为 [ − 1 , 1 ] [-1,1] [−1,1],权函数 ρ ( x ) 1 ρ(x)1 ρ(x)1时,由 1 , x , . . . , x n , . . . {1,x,...,x^n,...} 1,x,...,xn,...正交化得到的多项式称为勒让德多项式,并用 P 0 ( x ) , P 1 ( x ) ,…...
atc abc409E
原题链接:E - Pair Annihilation 题目背景: n 个点 n - 1 条边的有权无向图,每个点都有一个值,两个连通的点的值可以互相抵消,既将u 的 -1 传给 v 时可以抵消掉 v 的 1 并花费边权值;求最小花费。 考察算…...
Mysql批处理写入数据库
在学习mybatisPlus时,看到一个原本没用过的参数: rewriteBatchedStatementstrue 将上述代码装入jdbc的url中即可使数据库启用批处理写入。 需要注意的是,这个参数仅适用于MySQL JDBC 驱动的私有扩展参数。 作用原理是: 原本的…...

基于安卓的文件管理器程序开发研究源码数据库文档
摘 要 伴随着现代科技的发展潮流,移动互联网技术快速发展,各种基于通信技术的移动终端设备做的也越来越好了,现代智能手机大量的进入到了我们的生活中。电子产品的各种软硬技术技术的发展,操作系统的不断更新换代,谷歌…...

EMC VNXe 存储系统日志收集方法
写在前面 有朋友找来看看VNXe的故障,这种问题总是要收集日志,顺便这里也分享给大家。 注意,VNXe和VNX 属于完全不同的产品,不要看名字很类似,操作系统已经完全重构了,如果说是否有联系,大概就…...
嵌入式链表操作原理详解
嵌入式链表操作原理详解 链表是嵌入式软件开发中最基础的数据结构之一,其设计采用嵌入式链表节点的思想,实现了高度通用的链表管理机制。以下是核心原理和操作的全面解析: 一、基础数据结构 struct list_head {struct list_head *next, *pr…...

从“人找政策”到“政策找人”:智能退税ERP数字化重构外贸生态
离境退税新政核心内容与外贸企业影响 (一)政策核心变化解析 退税商店网络扩容 新政明确鼓励在大型商圈、旅游景区、交通枢纽等境外旅客聚集地增设退税商店,并放宽备案条件至纳税信用M级企业。以上海为例,静安区计划新增1000家退…...
一.设计模式的基本概念
一.核心概念 对软件设计中重复出现问题的成熟解决方案,提供代码可重用性、可维护性和扩展性保障。核心原则包括: 1.1. 单一职责原则 定义:一个类只承担一个职责,避免因职责过多导致的代码耦合。 1.2. 开闭原则 定义…...

以人类演示视频为提示,学习可泛化的机器人策略
25年5月来自清华大学、上海姚期智研究院和星动纪元(RoboEra)公司的论文“Learning Generalizable Robot Policy with Human Demonstration Video as a Prompt”。 最近的机器人学习方法通常依赖于从通过遥操作收集的大量机器人数据集中进行模仿学习…...
split方法
在编程中,split 方法通常用于将字符串按照指定的分隔符拆分成多个部分,并返回一个包含拆分结果的列表(或数组)。不同编程语言中的 split 方法语法略有不同,但核心功能相似。以下是常见语言中的用法: 1. P…...

SOC-ESP32S3部分:36-适配自己的板卡
飞书文档https://x509p6c8to.feishu.cn/wiki/RP4UwPrsKi4xuQkKLAAcKxD3n1b 如果你自己画了PCB板,需要把自己绘制的板卡配置小智AI工程,可以参考此文档。 下载源码 克隆或下载源码到本地,这里以1.5.5为例,大家可以自行修改其它版…...

LLMs 系列科普文(8)
八、模型的自我认知 接下来我们聊聊另一种问题,即模型的自我认知。 网上经常经常可以看到人们会问大语言模型一些关于认知方面的问题,比如“你是什么模型?谁创造了你?” 说实话,其实这个问题有点无厘头。 之所以这么…...
【明日方舟 × 红黑树】干员调度如何不掉线?算法工程的平衡魔法全揭秘!
【明日方舟 红黑树】干员调度如何不掉线?算法工程的平衡魔法全揭秘! 作者:星之辰 标签:#红黑树 #明日方舟 #工程平衡树 #算法科普 #动态数据结构 引子:为什么你的干员调度能实时平衡,从不崩盘?…...
Vue3 + Vite 中使用 Lodash-es 的防抖 debounce 详解
Vue3 Vite 中使用 Lodash-es 的防抖(debounce)详解 在 Vue3 Vite 项目中,debounce 是 lodash-es 中最常用的功能之一,它可以帮助我们优化高频事件的处理。下面我将详细讲解 debounce 的使用方法,并提供一个完整的示例。 Debounce 核心概念…...

机器学习基础相关问题
机器学习相关的基础问题 K-means是否一定会收敛 K-means是否一定会收敛 K-means算法在有限步数内一定会收敛,但收敛到的可能是局部最优解而非全局最优解。以下是详细分析: K-means 的优化目标是最小化 样本到其所归属簇中心的距离平方和(SSE…...

验证负载均衡与弹性伸缩
什么是弹性伸缩(Auto Scaling)? 弹性伸缩是指 云计算平台根据实时负载自动调整计算资源(如服务器实例、容器Pod)数量,以确保系统在高峰时保持稳定,在低谷时节省成本。 什么时候会触发弹性伸缩&…...

Three.js中AR实现详解并详细介绍基于图像标记模式AR生成的详细步骤
文档地址 Three.js中AR实现详解 以下是Three.js中实现AR功能的详细解析,涵盖技术原理、实现步骤、核心组件及优化策略: 🧩 一、技术基础 AR.js框架的核心作用 AR.js是Three.js实现AR的基石,提供以下核心能力: 多模…...
CSS高级技巧及新增属性
CSS高级技巧及新增属性 jarringslee 文章目录 CSS高级技巧及新增属性精灵图 Sprite字体图标 iconfontCSS几何图形的写法更改鼠标样式更改表单轮廓取消文本域的拖拽行内块元素的垂直居中对齐溢出文字处理 CSS布局技巧CSS5新增内容及其他属性新增选择器新增基础属性及其他属性ca…...

GeoBoundaries下载行政区划边界数据(提供中国资源shapefile)
要下载山东省济南市各个区的行政区划边界数据,你可以通过 geoBoundaries 提供的数据来实现。下面是详细步骤,包括网页操作和可选的 Python 自动化方式。 目录 ✅ 一、通过 geoBoundaries 官网手动下载1. 打开官网:2. 查找中国数据:…...
《深入理解 Nacos 集群与 Raft 协议》系列四:日志复制机制:Raft 如何确保提交可靠且幂等
《深入理解 Nacos 集群与 Raft 协议》系列 大家好,我是G探险者! 在前几篇中我们介绍了选主与日志对比机制,它们保证了“谁能成为 Leader”以及“Leader 的日志是否可靠”。 而当 Leader 已选定,系统需要把客户端的写请求写入所…...

大模型如何选型?嵌入模型如何选型?
欢迎来到啾啾的博客🐱。 记录学习点滴。分享工作思考和实用技巧,偶尔也分享一些杂谈💬。 有很多很多不足的地方,欢迎评论交流,感谢您的阅读和评论😄。 目录 引言模型优劣认知与模型选择大模型(L…...
float转换为整型过程中关于小数部分的处理
在大多数编程语言中,将 float 类型转换为整型时,小数部分不会自动进行四舍五入,而是会直接截断(即丢弃小数部分,仅保留整数部分)。具体行为可能因语言而异,以下是常见语言的示例: 1.…...

开源大模型网关:One API实现主流AI模型API的统一管理与分发
以下是对One API的简单介绍: One API是一个使用go语言开发的大语言模型 API 管理与分发系统支持Docker一键快速部署,且资源占用小,高性能开箱支持多平台大模型快速接入,包括OpenAI、Gemini、xAI、Grop、Anthropic Claude、Ollama…...
Java线程工厂:定制线程的利器
在Java中,线程工厂(Thread Factory)是一个创建新线程的工厂。它提供了一种方式,允许你在创建线程时定制线程的属性,比如设置线程名称、线程的优先级、守护线程属性等。 线程工厂的主要目的是将线程的创建逻辑从使用线…...

智慧充电:新能源汽车智慧充电桩的发展前景受哪些因素影响?
全球能源结构转型与碳中和目标的推进,新能源汽车产业迎来爆发式增长,而智慧充电桩作为其核心基础设施,发展前景备受关注。智慧充电不仅关乎用户充电体验的优化,更是电网平衡、能源效率提升的关键环节。 然而,其发展并…...
在Pnetlab6上绕过TPM、安全启动和 RAM 检查安装windows 11笔记
笔者本次安装的windows11的镜像为: zh-cn_windows_11_enterprise_ltsc_2024_x64_dvd_cff9cd2d.iso 1、创建镜像目录并上传iso文件 mkdir /opt/unetlab/addons/qemu/win-win11x64-2024-LTSC //目录名称务必按照官方文档格式,否则无法识别 目录创建完成后,将.iso格式镜像上…...