Redis开发05:使用stackexchange.redis库对redis进行增删改查
一、安装第三方库
二、官网
StackExchange.Redis |通用型 redis 客户端
三、连接示例
private static string redisConnectionString = "localhost:6379,password=yourpassword,defaultDatabase=0,allowAdmin=true,asyncTimeout=10000";
private static string redisConnectionString = "localhost:6379,defaultDatabase=0,allowAdmin=true,asyncTimeout=10000";
四、封装:增删改查
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
public class RedisData
{
/// <summary>
/// 键(包含冒号前的内容)
/// </summary>
public string Key { get; set; }
/// <summary>
/// 键尾
/// </summary>
public string KeyTail { get; set; }
/// <summary>
/// 值
/// </summary>
public string Value { get; set; }
/// <summary>
/// 剩余过期时间(天)
/// </summary>
public int? TTLDays { get; set; }
/// <summary>
/// 剩余过期时间(分钟)
/// </summary>
public int? TTLMins { get; set; }
/// <summary>
/// 剩余过期时间(秒)
/// </summary>
public int? TTLSecs { get; set; }
/// <summary>
/// 到期时间
/// </summary>
public DateTime? ExpirationTime { get; set; }
/// <summary>
/// 查询时间
/// </summary>
public DateTime QueryTime { get; set; }
}
public static class RedisExtension
{
// 默认的 Redis 连接字符串
private static string redisConnectionString = "localhost:6379,defaultDatabase=0,allowAdmin=true,asyncTimeout=10000";
// 使用 Lazy 实例化连接,只会在第一次使用时连接 Redis
private static Lazy<ConnectionMultiplexer> redis = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(redisConnectionString));
// 通过连接获取 Redis 数据库
private static IDatabase db => redis.Value.GetDatabase();
/// <summary>
/// 尝试连接
/// </summary>
/// <param name="conn"></param>
/// <returns></returns>
public static async Task<bool> TryConnectAsync(string conn = null)
{
// 如果传入了新的连接字符串,更新 Redis 连接
if (!string.IsNullOrWhiteSpace(conn))
{
redisConnectionString = conn;
// 清理现有连接,强制重新连接
redis = new Lazy<ConnectionMultiplexer>(() => ConnectionMultiplexer.Connect(redisConnectionString));
}
try
{
// 通过插入 测试 Redis 连接
string testKey = Guid.NewGuid().ToString();
await InsertAsync(testKey, testKey);
await DeleteAsync(testKey);
return true; // 连接成功
}
catch (Exception ex)
{
return false; // 连接失败
}
}
/// <summary>
/// 【增加】设置一个键值对
/// </summary>
/// <param name="key">第一个入参示例“NewYork:School:John”(文件夹形式);第三个入参可以传递形如TimeSpan.FromSeconds(30),传null则表明永不过期</param>
/// <param name="value"></param>
/// <param name="expiration"></param>
public static async Task<bool> InsertAsync(string key, string value, TimeSpan? expiration = null)
{
if (await GetRedisDataByKeyAsync(key) != null)
{
return false;
}
if (await db.KeyExistsAsync(key))
{
return false;
}
if (expiration == null) // 不设置超时时间
{
await db.StringSetAsync(key, value);
}
else // 设置超时时间
{
await db.StringSetAsync(key, value, expiration);
}
return true;
}
/// <summary>
/// 【更新】设置一个键值对
/// </summary>
/// <param name="key">第一个入参示例“NewYork:School:John”(文件夹形式);第三个入参可以传递形如TimeSpan.FromSeconds(30),传null则表明永不过期</param>
/// <param name="value"></param>
/// <param name="expiration"></param>
public static async Task<bool> UpdateAsync(string key, string value, TimeSpan? expiration = null)
{
if (await GetRedisDataByKeyAsync(key) == null)
{
return false;
}
if (expiration == null) // 不设置超时时间
{
await db.StringSetAsync(key, value);
}
else // 设置超时时间
{
await db.StringSetAsync(key, value, expiration);
}
return true;
}
/// <summary>
/// 【查询】键值对信息
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static async Task<RedisData> GetRedisDataByKeyAsync(string key)
{
if (await db.KeyExistsAsync(key)) // 键存在
{
RedisData data = new RedisData()
{
Key = key,
Value = await db.StringGetAsync(key),
KeyTail = key.Split(':').LastOrDefault(),
QueryTime = DateTime.Now
};
var ttl = await db.KeyTimeToLiveAsync(key);
if (ttl != null)
{
data.ExpirationTime = DateTime.Now.Add(ttl.Value);
data.TTLDays = Convert.ToInt32(ttl.Value.TotalDays);
data.TTLMins = Convert.ToInt32(ttl.Value.TotalMinutes);
data.TTLSecs = Convert.ToInt32(ttl.Value.TotalSeconds);
}
return data;
}
return null;
}
/// <summary>
/// 【删除】指定键,只有在键存在时才删除
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static async Task<bool> DeleteAsync(string key)
{
if (await db.KeyExistsAsync(key)) // 判断键是否存在
{
return await db.KeyDeleteAsync(key); // 如果存在,删除键
}
return false; // 如果键不存在,返回 false
}
/// <summary>
/// 【自定义指令(仅支持简单的)】
/// </summary>
/// 示例输入:PING INFO(查看配置信息) FLUSHDB(删除当前数据库所有键值对) FLUSHALL(删除所有数据库键值对)
/// <returns></returns>
public static async Task<string> SendCommandAsync(string command)
{
string result = "";
try
{
result = (await db.ExecuteAsync(command)).ToString();
return result; // 返回响应
}
catch (Exception ex)
{
return ex.Message.ToString();
}
}
/// <summary>
/// 【获取INFO配置信息】
/// </summary>
/// <returns></returns>
public static async Task<Dictionary<string, string>> GetInfo()
{
var splitlabel = ":";
var infos = await SendCommandAsync("INFO");
var infosList = infos.Split().Where(x => x.Contains(splitlabel));
var showdict = new Dictionary<string, string>();
foreach (var item in infosList)
{
var key = item.Split(splitlabel)[0].Trim();
var value = item.Split(splitlabel)[1].Trim();
switch (key)
{
case "redis_version":
showdict["版本号"] = value;
break;
case "redis_mode":
showdict["模式"] = value;
break;
case "role":
showdict["角色"] = value;
break;
case "process_id":
showdict["进程PID"] = value;
break;
case "tcp_port":
showdict["TCP端口"] = value;
break;
case "uptime_in_days":
showdict["服务已运行天数"] = value;
break;
case "hz":
showdict["每秒执行操作数"] = value;
break;
case "executable":
showdict["执行文件路径"] = value;
break;
case "config_file":
showdict["配置文件路径"] = value;//executable
break;
case "connected_clients":
showdict["当前连接数"] = value;
break;
case "blocked_clients":
showdict["阻塞数量"] = value;
break;
case "used_memory_human":
showdict["总使用内存"] = value;
break;
case "used_memory_rss_human":
showdict["物理内存"] = value;
break;
case "used_memory_peak_human":
showdict["峰值使用内存"] = value;
break;
case "maxmemory_policy":
showdict["内存回收策略"] = value;
break;
case "mem_fragmentation_ratio":
showdict["碎片比例"] = value;
break;
case "mem_allocator":
showdict["内存分配器"] = value;
break;
case "rdb_last_save_time":
showdict["RDB上次成功保存的时间"] = DateTimeOffset.FromUnixTimeSeconds(Convert.ToInt32(value)).LocalDateTime.ToString("yyyy年MM月dd日 HH时mm分ss秒");
break;
case "rdb_last_bgsave_status":
showdict["RDB上次保存的状态"] = value;
break;
case "aof_enabled":
showdict["是否启用 AOF 持久化"] = value;
break;
case "expired_keys":
showdict["过期的键数量"] = value;
break;
case "pubsub_channels":
showdict["当前的订阅频道数"] = value;
break;
case "pubsub_patterns":
showdict["当前的订阅模式数"] = value;
break;
case "latest_fork_usec":
showdict["最近一次 fork 操作的耗时(秒)"] = Math.Round(Convert.ToDouble(value)/1000,2).ToString();
break;
case "cluster_enabled":
showdict["是否启用集群模式"] = value;
break;
default:
break;
}
}
return showdict;
}
}
}