RedisHelper

Redis面试题:

1、什么是事务?2、Redis中有事务吗?3、Redis中的事务可以回滚吗?

答:

1、事务是指一个完整的动作,要么全部执行,要么什么也没有做

2、Redis中有事务,Redis 事务不是严格意义上的事务,只是用于帮助用户在一个步骤中执行多个命令。单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的

3、Redis 事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令回滚,也不会造成后续的指令不做

事务一般都是为原子性而生,既然Redis事务没有原子性,那他存在的意义是什么

答:redis事务的主要作用就是串联多个命令防止 别的命令插队。

RedisHelper封装

1、添加StackExchange.Redis引用

Install-Package StackExchange.Redis -Version 2.0.601

2、封装RedisHelper

using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
namespace Web.Common.Helper
{/// <summary>/// Redis 助手/// </summary>public class RedisHelper{/// <summary>/// 获取 Redis 连接对象/// </summary>/// <returns></returns>public IConnectionMultiplexer GetConnectionRedisMultiplexer(){if (_connMultiplexer == null || !_connMultiplexer.IsConnected)lock (Locker){if (_connMultiplexer == null || !_connMultiplexer.IsConnected)_connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString);}return _connMultiplexer;}#region 其它public ITransaction GetTransaction(){return _db.CreateTransaction();}#endregion 其它#region private field/// <summary>/// 连接字符串/// </summary>private static readonly string ConnectionString;/// <summary>/// redis 连接对象/// </summary>private static IConnectionMultiplexer _connMultiplexer;/// <summary>/// 默认的 Key 值(用来当作 RedisKey 的前缀)/// </summary>private static readonly string DefaultKey;/// <summary>/// 锁/// </summary>private static readonly object Locker = new object();/// <summary>/// 数据库/// </summary>private readonly IDatabase _db;#endregion private field#region 构造函数static RedisHelper(){//System.Configuration.ConfigurationManagervar configuration = new ConfigurationBuilder().SetBasePath(AppDomain.CurrentDomain.BaseDirectory).AddJsonFile("appsettings.json").Build();// 读取Redis连接字符串ConnectionString = configuration["Redis:Default:Connection"];_connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString);DefaultKey = configuration["Redis:DefaultKey"];AddRegisterEvent();}public RedisHelper(int db = 0){_db = _connMultiplexer.GetDatabase(db);}#endregion 构造函数#region String 操作/// <summary>/// 设置 key 并保存字符串(如果 key 已存在,则覆盖值)/// </summary>/// <param name="redisKey"></param>/// <param name="redisValue"></param>/// <param name="expiry"></param>/// <returns></returns>public bool StringSet(string redisKey, string redisValue, TimeSpan? expiry = null){redisKey = AddKeyPrefix(redisKey);return _db.StringSet(redisKey, redisValue, expiry);}/// <summary>/// 保存多个 Key-value/// </summary>/// <param name="keyValuePairs"></param>/// <returns></returns>public bool StringSet(IEnumerable<KeyValuePair<string, string>> keyValuePairs){var pairs = keyValuePairs.Select(x => new KeyValuePair<RedisKey, RedisValue>(AddKeyPrefix(x.Key), x.Value));return _db.StringSet(pairs.ToArray());}/// <summary>/// 获取字符串/// </summary>/// <param name="redisKey"></param>/// <param name="expiry"></param>/// <returns></returns>public string StringGet(string redisKey, TimeSpan? expiry = null){redisKey = AddKeyPrefix(redisKey);return _db.StringGet(redisKey);}/// <summary>/// 存储一个对象(该对象会被序列化保存)/// </summary>/// <param name="redisKey"></param>/// <param name="redisValue"></param>/// <param name="expiry"></param>/// <returns></returns>public bool StringSet<T>(string redisKey, T redisValue, TimeSpan? expiry = null){redisKey = AddKeyPrefix(redisKey);var json = Serialize(redisValue);return _db.StringSet(redisKey, json, expiry);}/// <summary>/// 获取一个对象(会进行反序列化)/// </summary>/// <param name="redisKey"></param>/// <param name="expiry"></param>/// <returns></returns>public T StringGet<T>(string redisKey, TimeSpan? expiry = null){redisKey = AddKeyPrefix(redisKey);return Deserialize<T>(_db.StringGet(redisKey));}#region async/// <summary>/// 保存一个字符串值/// </summary>/// <param name="redisKey"></param>/// <param name="redisValue"></param>/// <param name="expiry"></param>/// <returns></returns>public async Task<bool> StringSetAsync(string redisKey, string redisValue, TimeSpan? expiry = null){redisKey = AddKeyPrefix(redisKey);return await _db.StringSetAsync(redisKey, redisValue, expiry);}/// <summary>/// 保存一组字符串值/// </summary>/// <param name="keyValuePairs"></param>/// <returns></returns>public async Task<bool> StringSetAsync(IEnumerable<KeyValuePair<string, string>> keyValuePairs){var pairs = keyValuePairs.Select(x => new KeyValuePair<RedisKey, RedisValue>(AddKeyPrefix(x.Key), x.Value));return await _db.StringSetAsync(pairs.ToArray());}/// <summary>/// 获取单个值/// </summary>/// <param name="redisKey"></param>/// <param name="redisValue"></param>/// <param name="expiry"></param>/// <returns></returns>public async Task<string> StringGetAsync(string redisKey, string redisValue, TimeSpan? expiry = null){redisKey = AddKeyPrefix(redisKey);return await _db.StringGetAsync(redisKey);}/// <summary>/// 存储一个对象(该对象会被序列化保存)/// </summary>/// <param name="redisKey"></param>/// <param name="redisValue"></param>/// <param name="expiry"></param>/// <returns></returns>public async Task<bool> StringSetAsync<T>(string redisKey, T redisValue, TimeSpan? expiry = null){redisKey = AddKeyPrefix(redisKey);var json = Serialize(redisValue);return await _db.StringSetAsync(redisKey, json, expiry);}/// <summary>/// 获取一个对象(会进行反序列化)/// </summary>/// <param name="redisKey"></param>/// <param name="expiry"></param>/// <returns></returns>public async Task<T> StringGetAsync<T>(string redisKey, TimeSpan? expiry = null){redisKey = AddKeyPrefix(redisKey);return Deserialize<T>(await _db.StringGetAsync(redisKey));}#endregion async#endregion String 操作#region Hash 操作/// <summary>/// 判断该字段是否存在 hash 中/// </summary>/// <param name="redisKey"></param>/// <param name="hashField"></param>/// <returns></returns>public bool HashExists(string redisKey, string hashField){redisKey = AddKeyPrefix(redisKey);return _db.HashExists(redisKey, hashField);}/// <summary>/// 从 hash 中移除指定字段/// </summary>/// <param name="redisKey"></param>/// <param name="hashField"></param>/// <returns></returns>public bool HashDelete(string redisKey, string hashField){redisKey = AddKeyPrefix(redisKey);return _db.HashDelete(redisKey, hashField);}/// <summary>/// 从 hash 中移除指定字段/// </summary>/// <param name="redisKey"></param>/// <param name="hashFields"></param>/// <returns></returns>public long HashDelete(string redisKey, IEnumerable<string> hashFields){redisKey = AddKeyPrefix(redisKey);var fields = hashFields.Select(x => (RedisValue)x);return _db.HashDelete(redisKey, fields.ToArray());}/// <summary>/// 在 hash 设定值/// </summary>/// <param name="redisKey"></param>/// <param name="hashField"></param>/// <param name="value"></param>/// <returns></returns>public bool HashSet(string redisKey, string hashField, string value){redisKey = AddKeyPrefix(redisKey);return _db.HashSet(redisKey, hashField, value);}/// <summary>/// 在 hash 中设定值/// </summary>/// <param name="redisKey"></param>/// <param name="hashFields"></param>public void HashSet(string redisKey, IEnumerable<KeyValuePair<string, string>> hashFields){redisKey = AddKeyPrefix(redisKey);var entries = hashFields.Select(x => new HashEntry(x.Key, x.Value));_db.HashSet(redisKey, entries.ToArray());}/// <summary>/// 在 hash 中获取值/// </summary>/// <param name="redisKey"></param>/// <param name="hashField"></param>/// <returns></returns>public string HashGet(string redisKey, string hashField){redisKey = AddKeyPrefix(redisKey);return _db.HashGet(redisKey, hashField);}/// <summary>/// 在 hash 中获取值/// </summary>/// <param name="redisKey"></param>/// <param name="hashFields"></param>/// <returns></returns>public IEnumerable<string> HashGet(string redisKey, IEnumerable<string> hashFields){redisKey = AddKeyPrefix(redisKey);var fields = hashFields.Select(x => (RedisValue)x);return ConvertStrings(_db.HashGet(redisKey, fields.ToArray()));}/// <summary>/// 从 hash 返回所有的字段值/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public IEnumerable<string> HashKeys(string redisKey){redisKey = AddKeyPrefix(redisKey);return ConvertStrings(_db.HashKeys(redisKey));}/// <summary>/// 返回 hash 中的所有值/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public IEnumerable<string> HashValues(string redisKey){redisKey = AddKeyPrefix(redisKey);return ConvertStrings(_db.HashValues(redisKey));}/// <summary>/// 在 hash 设定值(序列化)/// </summary>/// <param name="redisKey"></param>/// <param name="hashField"></param>/// <param name="redisValue"></param>/// <returns></returns>public bool HashSet<T>(string redisKey, string hashField, T redisValue){redisKey = AddKeyPrefix(redisKey);var json = Serialize(redisValue);return _db.HashSet(redisKey, hashField, json);}/// <summary>/// 在 hash 中获取值(反序列化)/// </summary>/// <param name="redisKey"></param>/// <param name="hashField"></param>/// <returns></returns>public T HashGet<T>(string redisKey, string hashField){redisKey = AddKeyPrefix(redisKey);return Deserialize<T>(_db.HashGet(redisKey, hashField));}#region async/// <summary>/// 判断该字段是否存在 hash 中/// </summary>/// <param name="redisKey"></param>/// <param name="hashField"></param>/// <returns></returns>public async Task<bool> HashExistsAsync(string redisKey, string hashField){redisKey = AddKeyPrefix(redisKey);return await _db.HashExistsAsync(redisKey, hashField);}/// <summary>/// 从 hash 中移除指定字段/// </summary>/// <param name="redisKey"></param>/// <param name="hashField"></param>/// <returns></returns>public async Task<bool> HashDeleteAsync(string redisKey, string hashField){redisKey = AddKeyPrefix(redisKey);return await _db.HashDeleteAsync(redisKey, hashField);}/// <summary>/// 从 hash 中移除指定字段/// </summary>/// <param name="redisKey"></param>/// <param name="hashFields"></param>/// <returns></returns>public async Task<long> HashDeleteAsync(string redisKey, IEnumerable<string> hashFields){redisKey = AddKeyPrefix(redisKey);var fields = hashFields.Select(x => (RedisValue)x);return await _db.HashDeleteAsync(redisKey, fields.ToArray());}/// <summary>/// 在 hash 设定值/// </summary>/// <param name="redisKey"></param>/// <param name="hashField"></param>/// <param name="value"></param>/// <returns></returns>public async Task<bool> HashSetAsync(string redisKey, string hashField, string value){redisKey = AddKeyPrefix(redisKey);return await _db.HashSetAsync(redisKey, hashField, value);}/// <summary>/// 在 hash 中设定值/// </summary>/// <param name="redisKey"></param>/// <param name="hashFields"></param>public async Task HashSetAsync(string redisKey, IEnumerable<KeyValuePair<string, string>> hashFields){redisKey = AddKeyPrefix(redisKey);var entries = hashFields.Select(x => new HashEntry(AddKeyPrefix(x.Key), x.Value));await _db.HashSetAsync(redisKey, entries.ToArray());}/// <summary>/// 在 hash 中获取值/// </summary>/// <param name="redisKey"></param>/// <param name="hashField"></param>/// <returns></returns>public async Task<string> HashGetAsync(string redisKey, string hashField){redisKey = AddKeyPrefix(redisKey);return await _db.HashGetAsync(redisKey, hashField);}/// <summary>/// 在 hash 中获取值/// </summary>/// <param name="redisKey"></param>/// <param name="hashFields"></param>/// <param name="value"></param>/// <returns></returns>public async Task<IEnumerable<string>> HashGetAsync(string redisKey, IEnumerable<string> hashFields,string value){redisKey = AddKeyPrefix(redisKey);var fields = hashFields.Select(x => (RedisValue)x);return ConvertStrings(await _db.HashGetAsync(redisKey, fields.ToArray()));}/// <summary>/// 从 hash 返回所有的字段值/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public async Task<IEnumerable<string>> HashKeysAsync(string redisKey){redisKey = AddKeyPrefix(redisKey);return ConvertStrings(await _db.HashKeysAsync(redisKey));}/// <summary>/// 返回 hash 中的所有值/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public async Task<IEnumerable<string>> HashValuesAsync(string redisKey){redisKey = AddKeyPrefix(redisKey);return ConvertStrings(await _db.HashValuesAsync(redisKey));}/// <summary>/// 在 hash 设定值(序列化)/// </summary>/// <param name="redisKey"></param>/// <param name="hashField"></param>/// <param name="value"></param>/// <returns></returns>public async Task<bool> HashSetAsync<T>(string redisKey, string hashField, T value){redisKey = AddKeyPrefix(redisKey);var json = Serialize(value);return await _db.HashSetAsync(redisKey, hashField, json);}/// <summary>/// 在 hash 中获取值(反序列化)/// </summary>/// <param name="redisKey"></param>/// <param name="hashField"></param>/// <returns></returns>public async Task<T> HashGetAsync<T>(string redisKey, string hashField){redisKey = AddKeyPrefix(redisKey);return Deserialize<T>(await _db.HashGetAsync(redisKey, hashField));}#endregion async#endregion Hash 操作#region List 操作/// <summary>/// 移除并返回存储在该键列表的第一个元素/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public string ListLeftPop(string redisKey){redisKey = AddKeyPrefix(redisKey);return _db.ListLeftPop(redisKey);}/// <summary>/// 移除并返回存储在该键列表的最后一个元素/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public string ListRightPop(string redisKey){redisKey = AddKeyPrefix(redisKey);return _db.ListRightPop(redisKey);}/// <summary>/// 移除列表指定键上与该值相同的元素/// </summary>/// <param name="redisKey"></param>/// <param name="redisValue"></param>/// <returns></returns>public long ListRemove(string redisKey, string redisValue){redisKey = AddKeyPrefix(redisKey);return _db.ListRemove(redisKey, redisValue);}/// <summary>/// 在列表尾部插入值。如果键不存在,先创建再插入值/// </summary>/// <param name="redisKey"></param>/// <param name="redisValue"></param>/// <returns></returns>public long ListRightPush(string redisKey, string redisValue){redisKey = AddKeyPrefix(redisKey);return _db.ListRightPush(redisKey, redisValue);}/// <summary>/// 在列表头部插入值。如果键不存在,先创建再插入值/// </summary>/// <param name="redisKey"></param>/// <param name="redisValue"></param>/// <returns></returns>public long ListLeftPush(string redisKey, string redisValue){redisKey = AddKeyPrefix(redisKey);return _db.ListLeftPush(redisKey, redisValue);}/// <summary>/// 返回列表上该键的长度,如果不存在,返回 0/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public long ListLength(string redisKey){redisKey = AddKeyPrefix(redisKey);return _db.ListLength(redisKey);}/// <summary>/// 返回在该列表上键所对应的元素/// </summary>/// <param name="redisKey"></param>/// <param name="start"></param>/// <param name="stop"></param>/// <returns></returns>public IEnumerable<string> ListRange(string redisKey, long start = 0L, long stop = -1L){redisKey = AddKeyPrefix(redisKey);return ConvertStrings(_db.ListRange(redisKey, start, stop));}/// <summary>/// 移除并返回存储在该键列表的第一个元素/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public T ListLeftPop<T>(string redisKey){redisKey = AddKeyPrefix(redisKey);return Deserialize<T>(_db.ListLeftPop(redisKey));}/// <summary>/// 移除并返回存储在该键列表的最后一个元素/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public T ListRightPop<T>(string redisKey){redisKey = AddKeyPrefix(redisKey);return Deserialize<T>(_db.ListRightPop(redisKey));}/// <summary>/// 在列表尾部插入值。如果键不存在,先创建再插入值/// </summary>/// <param name="redisKey"></param>/// <param name="redisValue"></param>/// <returns></returns>public long ListRightPush<T>(string redisKey, T redisValue){redisKey = AddKeyPrefix(redisKey);return _db.ListRightPush(redisKey, Serialize(redisValue));}/// <summary>/// 在列表头部插入值。如果键不存在,先创建再插入值/// </summary>/// <param name="redisKey"></param>/// <param name="redisValue"></param>/// <returns></returns>public long ListLeftPush<T>(string redisKey, T redisValue){redisKey = AddKeyPrefix(redisKey);return _db.ListLeftPush(redisKey, Serialize(redisValue));}#region List-async/// <summary>/// 移除并返回存储在该键列表的第一个元素/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public async Task<string> ListLeftPopAsync(string redisKey){redisKey = AddKeyPrefix(redisKey);return await _db.ListLeftPopAsync(redisKey);}/// <summary>/// 移除并返回存储在该键列表的最后一个元素/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public async Task<string> ListRightPopAsync(string redisKey){redisKey = AddKeyPrefix(redisKey);return await _db.ListRightPopAsync(redisKey);}/// <summary>/// 移除列表指定键上与该值相同的元素/// </summary>/// <param name="redisKey"></param>/// <param name="redisValue"></param>/// <returns></returns>public async Task<long> ListRemoveAsync(string redisKey, string redisValue){redisKey = AddKeyPrefix(redisKey);return await _db.ListRemoveAsync(redisKey, redisValue);}/// <summary>/// 在列表尾部插入值。如果键不存在,先创建再插入值/// </summary>/// <param name="redisKey"></param>/// <param name="redisValue"></param>/// <returns></returns>public async Task<long> ListRightPushAsync(string redisKey, string redisValue){redisKey = AddKeyPrefix(redisKey);return await _db.ListRightPushAsync(redisKey, redisValue);}/// <summary>/// 在列表头部插入值。如果键不存在,先创建再插入值/// </summary>/// <param name="redisKey"></param>/// <param name="redisValue"></param>/// <returns></returns>public async Task<long> ListLeftPushAsync(string redisKey, string redisValue){redisKey = AddKeyPrefix(redisKey);return await _db.ListLeftPushAsync(redisKey, redisValue);}/// <summary>/// 返回列表上该键的长度,如果不存在,返回 0/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public async Task<long> ListLengthAsync(string redisKey){redisKey = AddKeyPrefix(redisKey);return await _db.ListLengthAsync(redisKey);}/// <summary>/// 返回在该列表上键所对应的元素/// </summary>/// <param name="redisKey"></param>/// <param name="start"></param>/// <param name="stop"></param>/// <returns></returns>public async Task<IEnumerable<string>> ListRangeAsync(string redisKey, long start = 0L, long stop = -1L){redisKey = AddKeyPrefix(redisKey);var query = await _db.ListRangeAsync(redisKey, start, stop);return query.Select(x => x.ToString());}/// <summary>/// 移除并返回存储在该键列表的第一个元素/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public async Task<T> ListLeftPopAsync<T>(string redisKey){redisKey = AddKeyPrefix(redisKey);return Deserialize<T>(await _db.ListLeftPopAsync(redisKey));}/// <summary>/// 移除并返回存储在该键列表的最后一个元素/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public async Task<T> ListRightPopAsync<T>(string redisKey){redisKey = AddKeyPrefix(redisKey);return Deserialize<T>(await _db.ListRightPopAsync(redisKey));}/// <summary>/// 在列表尾部插入值。如果键不存在,先创建再插入值/// </summary>/// <param name="redisKey"></param>/// <param name="redisValue"></param>/// <returns></returns>public async Task<long> ListRightPushAsync<T>(string redisKey, T redisValue){redisKey = AddKeyPrefix(redisKey);return await _db.ListRightPushAsync(redisKey, Serialize(redisValue));}/// <summary>/// 在列表头部插入值。如果键不存在,先创建再插入值/// </summary>/// <param name="redisKey"></param>/// <param name="redisValue"></param>/// <returns></returns>public async Task<long> ListLeftPushAsync<T>(string redisKey, T redisValue){redisKey = AddKeyPrefix(redisKey);return await _db.ListLeftPushAsync(redisKey, Serialize(redisValue));}#endregion List-async#endregion List 操作#region SortedSet 操作/// <summary>/// SortedSet 新增/// </summary>/// <param name="redisKey"></param>/// <param name="member"></param>/// <param name="score"></param>/// <returns></returns>public bool SortedSetAdd(string redisKey, string member, double score){redisKey = AddKeyPrefix(redisKey);return _db.SortedSetAdd(redisKey, member, score);}/// <summary>/// 在有序集合中返回指定范围的元素,默认情况下从低到高。/// </summary>/// <param name="redisKey"></param>/// <param name="start"></param>/// <param name="stop"></param>/// <param name="order"></param>/// <returns></returns>//public IEnumerable<string> SortedSetRangeByRank(string redisKey, long start = 0L, long stop = -1L,//    OrderType order = OrderType.Ascending)//{//    redisKey = AddKeyPrefix(redisKey);//    return _db.SortedSetRangeByRank(redisKey, start, stop, (Order)order).Select(x => x.ToString());//}/// <summary>/// 返回有序集合的元素个数/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public long SortedSetLength(string redisKey){redisKey = AddKeyPrefix(redisKey);return _db.SortedSetLength(redisKey);}/// <summary>/// 返回有序集合的元素个数/// </summary>/// <param name="redisKey"></param>/// <param name="memebr"></param>/// <returns></returns>public bool SortedSetLength(string redisKey, string memebr){redisKey = AddKeyPrefix(redisKey);return _db.SortedSetRemove(redisKey, memebr);}/// <summary>/// SortedSet 新增/// </summary>/// <param name="redisKey"></param>/// <param name="member"></param>/// <param name="score"></param>/// <returns></returns>public bool SortedSetAdd<T>(string redisKey, T member, double score){redisKey = AddKeyPrefix(redisKey);var json = Serialize(member);return _db.SortedSetAdd(redisKey, json, score);}/// <summary>/// 增量的得分排序的集合中的成员存储键值键按增量/// </summary>/// <param name="redisKey"></param>/// <param name="member"></param>/// <param name="value"></param>/// <returns></returns>public double SortedSetIncrement(string redisKey, string member, double value = 1){redisKey = AddKeyPrefix(redisKey);return _db.SortedSetIncrement(redisKey, member, value);}#region SortedSet-Async/// <summary>/// SortedSet 新增/// </summary>/// <param name="redisKey"></param>/// <param name="member"></param>/// <param name="score"></param>/// <returns></returns>public async Task<bool> SortedSetAddAsync(string redisKey, string member, double score){redisKey = AddKeyPrefix(redisKey);return await _db.SortedSetAddAsync(redisKey, member, score);}/// <summary>/// 在有序集合中返回指定范围的元素,默认情况下从低到高。/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public async Task<IEnumerable<string>> SortedSetRangeByRankAsync(string redisKey){redisKey = AddKeyPrefix(redisKey);return ConvertStrings(await _db.SortedSetRangeByRankAsync(redisKey));}/// <summary>/// 返回有序集合的元素个数/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public async Task<long> SortedSetLengthAsync(string redisKey){redisKey = AddKeyPrefix(redisKey);return await _db.SortedSetLengthAsync(redisKey);}/// <summary>/// 返回有序集合的元素个数/// </summary>/// <param name="redisKey"></param>/// <param name="memebr"></param>/// <returns></returns>public async Task<bool> SortedSetRemoveAsync(string redisKey, string memebr){redisKey = AddKeyPrefix(redisKey);return await _db.SortedSetRemoveAsync(redisKey, memebr);}/// <summary>/// SortedSet 新增/// </summary>/// <param name="redisKey"></param>/// <param name="member"></param>/// <param name="score"></param>/// <returns></returns>public async Task<bool> SortedSetAddAsync<T>(string redisKey, T member, double score){redisKey = AddKeyPrefix(redisKey);var json = Serialize(member);return await _db.SortedSetAddAsync(redisKey, json, score);}/// <summary>/// 增量的得分排序的集合中的成员存储键值键按增量/// </summary>/// <param name="redisKey"></param>/// <param name="member"></param>/// <param name="value"></param>/// <returns></returns>public Task<double> SortedSetIncrementAsync(string redisKey, string member, double value = 1){redisKey = AddKeyPrefix(redisKey);return _db.SortedSetIncrementAsync(redisKey, member, value);}#endregion SortedSet-Async#endregion SortedSet 操作#region key 操作/// <summary>/// 移除指定 Key/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public bool KeyDelete(string redisKey){redisKey = AddKeyPrefix(redisKey);return _db.KeyDelete(redisKey);}/// <summary>/// 移除指定 Key/// </summary>/// <param name="redisKeys"></param>/// <returns></returns>public long KeyDelete(IEnumerable<string> redisKeys){var keys = redisKeys.Select(x => (RedisKey)AddKeyPrefix(x));return _db.KeyDelete(keys.ToArray());}/// <summary>/// 校验 Key 是否存在/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public bool KeyExists(string redisKey){redisKey = AddKeyPrefix(redisKey);return _db.KeyExists(redisKey);}/// <summary>/// 重命名 Key/// </summary>/// <param name="redisKey"></param>/// <param name="redisNewKey"></param>/// <returns></returns>public bool KeyRename(string redisKey, string redisNewKey){redisKey = AddKeyPrefix(redisKey);return _db.KeyRename(redisKey, redisNewKey);}/// <summary>/// 设置 Key 的时间/// </summary>/// <param name="redisKey"></param>/// <param name="expiry"></param>/// <returns></returns>public bool KeyExpire(string redisKey, TimeSpan? expiry){redisKey = AddKeyPrefix(redisKey);return _db.KeyExpire(redisKey, expiry);}#region key-async/// <summary>/// 移除指定 Key/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public async Task<bool> KeyDeleteAsync(string redisKey){redisKey = AddKeyPrefix(redisKey);return await _db.KeyDeleteAsync(redisKey);}/// <summary>/// 移除指定 Key/// </summary>/// <param name="redisKeys"></param>/// <returns></returns>public async Task<long> KeyDeleteAsync(IEnumerable<string> redisKeys){var keys = redisKeys.Select(x => (RedisKey)AddKeyPrefix(x));return await _db.KeyDeleteAsync(keys.ToArray());}/// <summary>/// 校验 Key 是否存在/// </summary>/// <param name="redisKey"></param>/// <returns></returns>public async Task<bool> KeyExistsAsync(string redisKey){redisKey = AddKeyPrefix(redisKey);return await _db.KeyExistsAsync(redisKey);}/// <summary>/// 重命名 Key/// </summary>/// <param name="redisKey"></param>/// <param name="redisNewKey"></param>/// <returns></returns>public async Task<bool> KeyRenameAsync(string redisKey, string redisNewKey){redisKey = AddKeyPrefix(redisKey);return await _db.KeyRenameAsync(redisKey, redisNewKey);}/// <summary>/// 设置 Key 的时间/// </summary>/// <param name="redisKey"></param>/// <param name="expiry"></param>/// <returns></returns>public async Task<bool> KeyExpireAsync(string redisKey, TimeSpan? expiry){redisKey = AddKeyPrefix(redisKey);return await _db.KeyExpireAsync(redisKey, expiry);}#endregion key-async#endregion key 操作#region private method/// <summary>/// 添加 Key 的前缀/// </summary>/// <param name="key"></param>/// <returns></returns>private static string AddKeyPrefix(string key){return DefaultKey + ":" + key;}/// <summary>/// 转换为字符串/// </summary>/// <typeparam name="T"></typeparam>/// <param name="list"></param>/// <returns></returns>private static IEnumerable<string> ConvertStrings<T>(IEnumerable<T> list) where T : struct{if (list == null) throw new ArgumentNullException(nameof(list));return list.Select(x => x.ToString());}#region 注册事件/// <summary>/// 添加注册事件/// </summary>private static void AddRegisterEvent(){_connMultiplexer.ConnectionRestored += ConnMultiplexer_ConnectionRestored;_connMultiplexer.ConnectionFailed += ConnMultiplexer_ConnectionFailed;_connMultiplexer.ErrorMessage += ConnMultiplexer_ErrorMessage;_connMultiplexer.ConfigurationChanged += ConnMultiplexer_ConfigurationChanged;_connMultiplexer.HashSlotMoved += ConnMultiplexer_HashSlotMoved;_connMultiplexer.InternalError += ConnMultiplexer_InternalError;_connMultiplexer.ConfigurationChangedBroadcast += ConnMultiplexer_ConfigurationChangedBroadcast;}/// <summary>/// 重新配置广播时(通常意味着主从同步更改)/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private static void ConnMultiplexer_ConfigurationChangedBroadcast(object sender, EndPointEventArgs e){Console.WriteLine($"{nameof(ConnMultiplexer_ConfigurationChangedBroadcast)}: {e.EndPoint}");}/// <summary>/// 发生内部错误时(主要用于调试)/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private static void ConnMultiplexer_InternalError(object sender, InternalErrorEventArgs e){Console.WriteLine($"{nameof(ConnMultiplexer_InternalError)}: {e.Exception}");}/// <summary>/// 更改集群时/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private static void ConnMultiplexer_HashSlotMoved(object sender, HashSlotMovedEventArgs e){Console.WriteLine($"{nameof(ConnMultiplexer_HashSlotMoved)}: {nameof(e.OldEndPoint)}-{e.OldEndPoint} To {nameof(e.NewEndPoint)}-{e.NewEndPoint}, ");}/// <summary>/// 配置更改时/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private static void ConnMultiplexer_ConfigurationChanged(object sender, EndPointEventArgs e){Console.WriteLine($"{nameof(ConnMultiplexer_ConfigurationChanged)}: {e.EndPoint}");}/// <summary>/// 发生错误时/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private static void ConnMultiplexer_ErrorMessage(object sender, RedisErrorEventArgs e){Console.WriteLine($"{nameof(ConnMultiplexer_ErrorMessage)}: {e.Message}");}/// <summary>/// 物理连接失败时/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private static void ConnMultiplexer_ConnectionFailed(object sender, ConnectionFailedEventArgs e){Console.WriteLine($"{nameof(ConnMultiplexer_ConnectionFailed)}: {e.Exception}");}/// <summary>/// 建立物理连接时/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private static void ConnMultiplexer_ConnectionRestored(object sender, ConnectionFailedEventArgs e){Console.WriteLine($"{nameof(ConnMultiplexer_ConnectionRestored)}: {e.Exception}");}#endregion 注册事件/// <summary>/// 序列化/// </summary>/// <param name="obj"></param>/// <returns></returns>private static byte[] Serialize(object obj){if (obj == null)return null;var binaryFormatter = new BinaryFormatter();using (var memoryStream = new MemoryStream()){binaryFormatter.Serialize(memoryStream, obj);var data = memoryStream.ToArray();return data;}}/// <summary>/// 反序列化/// </summary>/// <typeparam name="T"></typeparam>/// <param name="data"></param>/// <returns></returns>private static T Deserialize<T>(byte[] data){if (data == null)return default(T);var binaryFormatter = new BinaryFormatter();using (var memoryStream = new MemoryStream(data)){var result = (T)binaryFormatter.Deserialize(memoryStream);return result;}}#endregion private method}
}

使用方式

 RedisHelper redis = new RedisHelper(0); //0是库var s = redis.StringSet("myname", "abc3");var n = redis.StringGet("myname");

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

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

相关文章

分页操作中使用LIMIT和OFFSET后出现慢查询的原因分析

事情经过 最近在做批量数据处理的相关业务&#xff0c;在和下游对接时&#xff0c;发现拉取他们的业务数据刚开始很快&#xff0c;后面会越来越慢&#xff0c;40万数据一个小时都拉不完。经过排查后&#xff0c;发现对方用了很坑的分页查询方式 —— LIMIT OFFSET&#xff0c;…

【前端学习记录】Vue前端规范整理

文章目录 前言一、文件及文件夹命名二、钩子顺序三、注释规范四、组件封装五、CSS编码规范六、JS编码规范 前言 优秀的项目源码&#xff0c;即使是多人开发&#xff0c;看代码也如一人之手。统一的编码规范&#xff0c;可使代码更易于阅读&#xff0c;易于理解&#xff0c;易于…

mysql中NULL值

mysql中NULL值表示“没有值”&#xff0c;它跟空字符串""是不同的 例如&#xff0c;执行下面两个插入记录的语句&#xff1a; insert into test_table (description) values (null); insert into test_table (description) values ();执行以后&#xff0c;查看表的…

harmonyOS鸿蒙内核概述

内核概述 内核简介 用户最常见到并与之交互的操作系统界面&#xff0c;其实只是操作系统最外面的一层。操作系统最重要的任务&#xff0c;包括管理硬件设备&#xff0c;分配系统资源等&#xff0c;我们称之为操作系统内在最重要的核心功能。而实现这些核心功能的操作系统模块…

2023年全国职业院校技能大赛信息安全管理与评估正式赛(模块三理论技能)

2023年全国职业院校技能大赛&#xff08;高等职业教育组&#xff09;“信息安全管理与评估”理论技能 理论技能与职业素养&#xff08;100分&#xff09; 【注意事项】 1.理论测试前请仔细阅读测试系统使用说明文档&#xff0c;按提供的账号和密码登录测试系统进行测试&…

【经验分享】gemini-pro和gemini-pro-vision使用体验

Gemini Gemini已经对开发者开放了Gemini Pro的使用权限&#xff0c;目前对大家都是免费的&#xff0c;每分钟限制60条&#xff0c;至少这比起CloseAI的每个账户5刀限速1min3条要香的多&#xff0c;目前已于第一时间进行了体验 一句话总结&#xff0c;google很大方&#xff0c;但…

【Spring】@SpringBootApplication注解解析

前言&#xff1a; 当我们第一次创建一个springboot工程时&#xff0c;我们会对启动类&#xff08;xxxApplication&#xff09;有许多困惑&#xff0c;为什么只要运行启动类我们在项目中自定义的bean无需配置类配置&#xff0c;扫描就能自动注入到IOC容器中&#xff1f;为什么我…

仿牛客论坛的一些细节改进

私信列表的会话头像链接到个人主页 原来的不足 点击私信列表的会话头像应该要能跳转到该目标对象的个人主页。 原来的代码&#xff1a; <a href"profile.html"><img th:src"${map.target.headerUrl}" class"mr-4 rounded-circle user-he…

三、Java运算符

1.运算符和表达式 运算符&#xff1a; ​ 就是对常量或者变量进行操作的符号。 ​ 比如&#xff1a; - * / 表达式&#xff1a; ​ 用运算符把常量或者变量连接起来的&#xff0c;符合Java语法的式子就是表达式。 ​ 比如&#xff1a;a b 这个整体就是表达式。 ​ 而其…

数据分析为何要学统计学(4)——何为置信区间?它有什么作用?

置信区间是统计学中的一个重要工具&#xff0c;是用样本参数()估计出来的总体均值在某置信水平下的范围。通俗一点讲&#xff0c;如果置信度为95%&#xff08;等价于显著水平a0.05&#xff09;&#xff0c;置信区间为[a,b]&#xff0c;这就意味着总体均值落入该区间的概率为95%…

Two Phase Termination(两阶段)设计模式

Two Phase Termination设计模式是针对任务由两个环节组成&#xff0c;第一个环节是处理业务相关的内容&#xff0c;第二个阶段是处理任务结束时的同步、释放资源等操作。在进行两阶段终结的时候&#xff0c;需要考虑&#xff1a; 第二阶段终止操作必须保证线程安全。 要百分百…

2036开关门,1109开关门

一&#xff1a;2036开关门 1.1题目 1.2思路 1.每次都是房间号是服务员的倍数的时候做处理&#xff0c;所以外层&#xff08;i&#xff09;枚举服务员1~n&#xff0c;内层&#xff08;j&#xff09;枚举房间号1~n&#xff0c;当j % i0时&#xff0c;做处理 2.这个处理指的是&…

小项目:迷宫

目录 引言1.题目描述及思想2.代码实现3.最终结果 引言 这个迷宫的话就是去年这时候&#xff0c;我记得当时讲这个的时候我还是一脸懵逼&#xff0c;就是事后花时间能够看懂&#xff0c;能够理解&#xff0c;但是自己肯定是不能够实现的&#xff0c;而且觉得这个东西非常的庞大…

IIC和SPI结合实现室内温度计

iic.h #ifndef __IIC_H__ #define __IIC_H__ #include "stm32mp1xx_gpio.h" #include "stm32mp1xx_rcc.h" #include "gpio.h" /* 通过程序模拟实现I2C总线的时序和协议* GPIOF ---> AHB4* I2C1_SCL ---> PF14* I2C1_SDA ---> PF15** *…

facebook广告的门槛有哪些

Facebook广告的门槛主要包括以下几个方面&#xff1a; 账户资格&#xff1a;需要拥有一个有效的Facebook个人账号或商业账号。 账户状态&#xff1a;个人账号需要满足一定活跃度要求&#xff0c;而商业账号则需要满足公司名称和地址等详细信息的要求。 账户安全性&#xff1a…

每日一题:Leetcode974.和可被k整除的子数组

题目描述&#xff1a; 给定一个整数数组 nums 和一个整数 k &#xff0c;返回其中元素之和可被 k 整除的&#xff08;连续、非空&#xff09; 子数组 的数目。 子数组 是数组的 连续 部分。 示例 1&#xff1a; 输入&#xff1a;nums [4,5,0,-2,-3,1], k 5 输出&#xff1…

什么是PHPUnit?如何进行单元测试?

PHPUnit 是一个用于 PHP 的单元测试框架&#xff0c;它支持测试驱动开发&#xff08;TDD&#xff09;和行为驱动开发&#xff08;BDD&#xff09;。PHPUnit 提供了一套用于编写和运行测试的工具和断言方法。 以下是使用 PHPUnit 进行单元测试的基本步骤&#xff1a; 步骤 1: …

【LeetCode刷题笔记(4)】【Python】【移动零】【简单】

文章目录 题目描述示例 1示例 2提示 解决方案题意拆解双指针算法双指针法的主要优点双指针法的使用场景举例&#xff1a; 解决方案&#xff1a;【双指针一次遍历】解题心得方案代码运行结果复杂度分析 结束语 移动零 题目描述 给定一个数组 nums&#xff0c;编写一个函数将所…

代码随想录第三十一天(一刷C语言)|无重叠区间划分字母区间合并区间

创作目的&#xff1a;为了方便自己后续复习重点&#xff0c;以及养成写博客的习惯。 一、无重叠区间 思路&#xff1a;参考carl文档 按照右边界排序&#xff0c;从左向右记录非交叉区间的个数。最后用区间总数减去非交叉区间的个数就是需要移除的区间个数了。 ledcode题目&a…

多线程------ThreadLocal详解

目录 1. 什么是 ThreadLocal&#xff1f; 2. 如何使用 ThreadLocal&#xff1f; 3. ThreadLocal 的作用 4. ThreadLocal 的应用场景 5. ThreadLocal 的注意事项 我的其他博客 ThreadLocal 是 Java 中一个很有用的类&#xff0c;它提供了线程局部变量的支持。线程局部变量…