在.Net下使用redis基于StackExchange.Redis

2024-02-23 21:30
文章标签 使用 redis net stackexchange

本文主要是介绍在.Net下使用redis基于StackExchange.Redis,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

研究了下redis在.net下的使用,因为以前在java上用redis用的是jedis操作,在.net不是很熟悉,在网站上也看了一部分的.net下redis的使用,大部分都是ServiceStack.Redis听说ServiceStack.Redis4.0版本都是收费的,这个我不是很清楚,但是我确实有项目再用ServiceStack.Redis。

这里就不讨论ServiceStack.Redis的使用今天带来的是StackExchange.Redis的封装版。

代码参考

DDD领域驱动之干货(三)完结篇!

下面是干货

RedisCaching里面放着的是Redis的基本5个方法分别如下图所示:

RedisCommon里面放着的是redis的帮助类和初始化类如下图所示:

现在举了例子就以DoRedisStringCache为例:

实现了接口IRedisCaching,当然这里这个接口是标识接口意思就是用来约束的。

StackExchange.Redis是初始化是单列模式,内部有一套自己的方法,这里我就放一下代码

 

这里面还有6个事件如下图:

代码贴出来:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StackExchange.Redis;
using KuRuMi.Mio.DoMain.Infrastructure.Logger;namespace KuRuMi.Mio.DoMain.RedisCache.RedisCommon
{public class RedisManager{private static string Constring = RedisConfig.Config();private static readonly object locker = new object();private static ConnectionMultiplexer instance;private static readonly Dictionary<string, ConnectionMultiplexer> Concache = new Dictionary<string, ConnectionMultiplexer>();/// <summary>/// 单例模式获取redis连接实例/// </summary>public static ConnectionMultiplexer Instance{get{if (instance == null){lock (locker){if (instance == null)instance = GetManager();}}return instance;}}/// <summary>/// 从缓存中获取/// </summary>/// <param name="constr"></param>/// <returns></returns>public static ConnectionMultiplexer GetConForMap(string constr) {if (!Concache.ContainsKey(constr))Concache[constr] = GetManager(constr);return Concache[constr];}private static ConnectionMultiplexer GetManager(string constr = null){constr = constr ?? Constring;var connect = ConnectionMultiplexer.Connect(constr);#region 注册事件connect.ConnectionFailed += MuxerConnectionFailed;connect.ConnectionRestored += MuxerConnectionRestored;connect.ErrorMessage += MuxerErrorMessage;connect.ConfigurationChanged += MuxerConfigurationChanged;connect.HashSlotMoved += MuxerHashSlotMoved;connect.InternalError += MuxerInternalError;#endregionreturn connect;}#region Redis事件/// <summary>/// 内部异常/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private static void MuxerInternalError(object sender, InternalErrorEventArgs e){Units.Log("内部异常:" + e.Exception.Message);}/// <summary>/// 集群更改/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private static void MuxerHashSlotMoved(object sender, HashSlotMovedEventArgs e){Units.Log("新集群:" + e.NewEndPoint + "旧集群:" + e.OldEndPoint);}/// <summary>/// 配置更改事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private static void MuxerConfigurationChanged(object sender, EndPointEventArgs e){Units.Log("配置更改:" + e.EndPoint);}/// <summary>/// 错误事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private static void MuxerErrorMessage(object sender, RedisErrorEventArgs e){Units.Log("异常信息:" + e.Message);}/// <summary>/// 重连错误事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private static void MuxerConnectionRestored(object sender, ConnectionFailedEventArgs e){Units.Log("重连错误" + e.EndPoint);}/// <summary>/// 连接失败事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private static void MuxerConnectionFailed(object sender, ConnectionFailedEventArgs e){Units.Log("连接异常" + e.EndPoint + ",类型为" + e.FailureType + (e.Exception == null ? "" : (",异常信息是" + e.Exception.Message)));}#endregion}
}

下面是redis的config:

using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace KuRuMi.Mio.DoMain.RedisCache.RedisCommon
{public sealed class RedisConfig{public static readonly string config = ConfigurationManager.AppSettings["RedisConfig"];public static readonly string redisKey = ConfigurationManager.AppSettings["RedisKey"] ?? "";public static string Config() {return config;}public static string Key() {return redisKey;}}
}

下面是redis的helper:

using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace KuRuMi.Mio.DoMain.RedisCache.RedisCommon
{public class RedisBase{private static ConnectionMultiplexer db = null;private static string key = string.Empty;private int DbNumber { get; }public RedisBase(int dbnum = 0) : this(dbnum, null){}public RedisBase(int dbnum, string connectionString){DbNumber = dbnum;db = string.IsNullOrWhiteSpace(connectionString) ? RedisManager.Instance : RedisManager.GetConForMap(connectionString);}#region 辅助方法/// <summary>/// 添加名称/// </summary>/// <param name="old"></param>/// <returns></returns>public string AddKey(string old){var fixkey = key ?? RedisConfig.Key();return fixkey + old;}/// <summary>/// 执行保存/// </summary>/// <typeparam name="T"></typeparam>/// <param name="func"></param>/// <returns></returns>public T DoSave<T>(Func<IDatabase, T> func){return func(db.GetDatabase(DbNumber));}public string ConvertJson<T>(T val){return val is string ? val.ToString() : JsonConvert.SerializeObject(val);}public T ConvertObj<T>(RedisValue val){return JsonConvert.DeserializeObject<T>(val);}public List<T> ConvertList<T>(RedisValue[] val){List<T> result = new List<T>();foreach (var item in val){var model = ConvertObj<T>(item);result.Add(model);}return result;}public RedisKey[] ConvertRedisKeys(List<string> val){return val.Select(k => (RedisKey)k).ToArray();}#endregion}
}

下面是我的string封装方法:

using KuRuMi.Mio.DoMain.RedisCache.RedisCommon;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace KuRuMi.Mio.DoMain.RedisCache.RedisCaching
{/// <summary>/// 表示string的操作/// </summary>public class DoRedisStringCache : IRedisCaching{private RedisBase redis = null;public DoRedisStringCache(){redis = new RedisBase();}#region 同步执行/// <summary>/// 单个保存/// </summary>/// <param name="key"></param>/// <param name="val"></param>/// <param name="exp">过期时间</param>/// <returns></returns>public bool StringSet(string key, string val, TimeSpan? exp = default(TimeSpan?)){key = redis.AddKey(key);return redis.DoSave(db => db.StringSet(key, val, exp));}/// <summary>/// 保存多个key value/// </summary>/// <param name="keyValues">键值对</param>/// <returns></returns>public bool StringSet(List<KeyValuePair<RedisKey, RedisValue>> KeyVal){List<KeyValuePair<RedisKey, RedisValue>> newkey = KeyVal.Select(k => new KeyValuePair<RedisKey, RedisValue>(redis.AddKey(k.Key), k.Value)).ToList();return redis.DoSave(db => db.StringSet(newkey.ToArray()));}/// <summary>/// 保存一个对象/// </summary>/// <typeparam name="T"></typeparam>/// <param name="key"></param>/// <param name="obj"></param>/// <param name="exp"></param>/// <returns></returns>public bool StringSet<T>(string key, T obj, TimeSpan? exp = default(TimeSpan?)){key = redis.AddKey(key);string json = redis.ConvertJson(obj);return redis.DoSave(db => db.StringSet(key, json, exp));}/// <summary>/// 获取单个/// </summary>/// <param name="key"></param>/// <returns></returns>public string StringGet(string key){key = redis.AddKey(key);return redis.DoSave(db => db.StringGet(key));}/// <summary>/// 获取单个对象/// </summary>/// <typeparam name="T"></typeparam>/// <param name="key"></param>/// <returns></returns>public T StringGet<T>(string key) {key = redis.AddKey(key);var val = redis.DoSave(db => db.StringGet(key));return redis.ConvertObj<T>(val);}/// <summary>/// 为数字增长val/// </summary>/// <param name="key"></param>/// <param name="val">可以为负数</param>/// <returns>增长后的值</returns>public double StringIncrement(string key, double val = 1){key = redis.AddKey(key);return redis.DoSave(db => db.StringIncrement(key, val));}/// <summary>/// 为数字减少val/// </summary>/// <param name="key"></param>/// <param name="val">可以为负数</param>/// <returns>增长后的值</returns>public double StringDecrement(string key, double val = 1){key = redis.AddKey(key);return redis.DoSave(db => db.StringDecrement(key, val));}#endregion#region 异步执行/// <summary>/// 异步保存单个/// </summary>/// <param name="key"></param>/// <param name="val"></param>/// <param name="exp"></param>/// <returns></returns>public async Task<bool> StringSetAsync(string key, string val, TimeSpan? exp = default(TimeSpan?)){key = redis.AddKey(key);return await redis.DoSave(db => db.StringSetAsync(key, val, exp));}/// <summary>/// 异步保存多个key value/// </summary>/// <param name="keyValues">键值对</param>/// <returns></returns>public async Task<bool> StringSetAsync(List<KeyValuePair<RedisKey, RedisValue>> KeyVal){List<KeyValuePair<RedisKey, RedisValue>> newkey = KeyVal.Select(k => new KeyValuePair<RedisKey, RedisValue>(redis.AddKey(k.Key), k.Value)).ToList();return await redis.DoSave(db => db.StringSetAsync(newkey.ToArray()));}/// <summary>/// 异步保存一个对象/// </summary>/// <typeparam name="T"></typeparam>/// <param name="key"></param>/// <param name="obj"></param>/// <param name="exp"></param>/// <returns></returns>public async Task<bool> StringSetAsync<T>(string key, T obj, TimeSpan? exp = default(TimeSpan?)){key = redis.AddKey(key);string json = redis.ConvertJson(obj);return await redis.DoSave(db => db.StringSetAsync(key, json, exp));}/// <summary>/// 异步获取单个/// </summary>/// <param name="key"></param>/// <returns></returns>public async Task<string> StringGetAsync(string key){key = redis.AddKey(key);return await redis.DoSave(db => db.StringGetAsync(key));}/// <summary>/// 异步获取单个/// </summary>/// <param name="key"></param>/// <returns></returns>public async Task<T> StringGetAsync<T>(string key){key = redis.AddKey(key);var val = await redis.DoSave(db => db.StringGetAsync(key));return redis.ConvertObj<T>(val);}/// <summary>/// 异步为数字增长val/// </summary>/// <param name="key"></param>/// <param name="val">可以为负数</param>/// <returns>增长后的值</returns>public async Task<double> StringIncrementAsync(string key, double val = 1){key = redis.AddKey(key);return await redis.DoSave(db => db.StringIncrementAsync(key, val));}/// <summary>/// 为数字减少val/// </summary>/// <param name="key"></param>/// <param name="val">可以为负数</param>/// <returns>增长后的值</returns>public async Task<double> StringDecrementAsync(string key, double val = 1){key = redis.AddKey(key);return await redis.DoSave(db => db.StringDecrementAsync(key, val));}#endregion}
}

StackExchange.Redis本身提供了一套异步的方法这个我比较喜欢。至于其他的和string的同理,我这里就不放出封装方法,需要的留言。

最后是测试:

这是我的redis然后是我的数据库

这里是我登录的测试代码:

 

转载于:https://www.cnblogs.com/edna-lzh/p/6932948.html

这篇关于在.Net下使用redis基于StackExchange.Redis的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/739974

相关文章

使用Python实现IP地址和端口状态检测与监控

《使用Python实现IP地址和端口状态检测与监控》在网络运维和服务器管理中,IP地址和端口的可用性监控是保障业务连续性的基础需求,本文将带你用Python从零打造一个高可用IP监控系统,感兴趣的小伙... 目录概述:为什么需要IP监控系统使用步骤说明1. 环境准备2. 系统部署3. 核心功能配置系统效果展

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

redis中使用lua脚本的原理与基本使用详解

《redis中使用lua脚本的原理与基本使用详解》在Redis中使用Lua脚本可以实现原子性操作、减少网络开销以及提高执行效率,下面小编就来和大家详细介绍一下在redis中使用lua脚本的原理... 目录Redis 执行 Lua 脚本的原理基本使用方法使用EVAL命令执行 Lua 脚本使用EVALSHA命令

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

使用Python和Pyecharts创建交互式地图

《使用Python和Pyecharts创建交互式地图》在数据可视化领域,创建交互式地图是一种强大的方式,可以使受众能够以引人入胜且信息丰富的方式探索地理数据,下面我们看看如何使用Python和Pyec... 目录简介Pyecharts 简介创建上海地图代码说明运行结果总结简介在数据可视化领域,创建交互式地

Redis 热 key 和大 key 问题小结

《Redis热key和大key问题小结》:本文主要介绍Redis热key和大key问题小结,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录一、什么是 Redis 热 key?热 key(Hot Key)定义: 热 key 常见表现:热 key 的风险:二、

Java Stream流使用案例深入详解

《JavaStream流使用案例深入详解》:本文主要介绍JavaStream流使用案例详解,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录前言1. Lambda1.1 语法1.2 没参数只有一条语句或者多条语句1.3 一个参数只有一条语句或者多

Java Spring 中 @PostConstruct 注解使用原理及常见场景

《JavaSpring中@PostConstruct注解使用原理及常见场景》在JavaSpring中,@PostConstruct注解是一个非常实用的功能,它允许开发者在Spring容器完全初... 目录一、@PostConstruct 注解概述二、@PostConstruct 注解的基本使用2.1 基本代

C#使用StackExchange.Redis实现分布式锁的两种方式介绍

《C#使用StackExchange.Redis实现分布式锁的两种方式介绍》分布式锁在集群的架构中发挥着重要的作用,:本文主要介绍C#使用StackExchange.Redis实现分布式锁的... 目录自定义分布式锁获取锁释放锁自动续期StackExchange.Redis分布式锁获取锁释放锁自动续期分布式

springboot使用Scheduling实现动态增删启停定时任务教程

《springboot使用Scheduling实现动态增删启停定时任务教程》:本文主要介绍springboot使用Scheduling实现动态增删启停定时任务教程,具有很好的参考价值,希望对大家有... 目录1、配置定时任务需要的线程池2、创建ScheduledFuture的包装类3、注册定时任务,增加、删