using System;
using System.Linq;
using StackExchange.Redis;
using System.Configuration;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Threading.Tasks;
using System.Runtime.Serialization;
namespace macco.bidding.tradingui.Toolkit.Redis
{
/// <summary>
/// 这是一个手动封装的完整RedisHelper
/// </summary>
public class RedisHelper
{
/// <summary>
/// 连接字符串
/// </summary>
private static readonly string ConnectionString;
/// <summary>
/// redis 连接对象
/// </summary>
private static IConnectionMultiplexer _connMultiplexer;
/// <summary>
/// 默认的key值(用来当作RedisKey的前缀)
/// </summary>
public static string DefaultKey {
get; private set; }
/// <summary>
/// 锁
/// </summary>
private static readonly object Locker = new object();
/// <summary>
/// 数据库访问对象
/// </summary>
private readonly IDatabase _db;
/// <summary>
/// 采用双重锁单例模式,保证数据访问对象有且仅有一个
/// </summary>
/// <returns></returns>
public IConnectionMultiplexer GetConnectionRedisMultiplexer()
{
if ((_connMultiplexer == null || !_connMultiplexer.IsConnected))
{
lock (Locker)
{
if ((_connMultiplexer == null || !_connMultiplexer.IsConnected))
{
_connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString);
}
}
}
return _connMultiplexer;
}
/// <summary>
/// 添加事务处理
/// </summary>
/// <returns></returns>
public ITransaction GetTransaction()
{
//创建事务
return _db.CreateTransaction();
}
#region 构造函数
/// <summary>
/// 静态的构造函数,
/// 构造函数是属于类的,而不是属于实例的
/// 就是说这个构造函数只会被执行一次。也就是在创建第一个实例或引用任何静态成员之前,由.NET自动调用。
/// </summary>
static RedisHelper()
{
ConnectionString = System.Configuration.ConfigurationManager.AppSettings["RedidServerAddress"];
_connMultiplexer = ConnectionMultiplexer.Connect(ConnectionString);
DefaultKey = System.Configuration.ConfigurationManager.AppSettings["DefaultKey"];
RegisterEvent();
}
/// <summary>
/// 重载构造器,获取redis内部数据库的交互式连接
/// </summary>
/// <param name="db">要获取的数据库ID</param>
public RedisHelper(int db = -1)
{
_db = _connMultiplexer.GetDatabase(db);
}
#endregion
#region 通用方法
/// <summary>
/// 添加 key 的前缀
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
private static string AddKeyPrefix(string key)
{
return $"{DefaultKey}:{key}";
}
/// <summary>
/// 序列化,用于存储对象
/// </summary>
/// <param name="obj"></param>
/// <returns></returns>
private static byte[] Serialize(object obj)
{
try
{
if (obj == null)
return null;
var binaryFormatter = new BinaryFormatter();
using (var memoryStream = new MemoryStream())
{
binaryFormatter.Serialize(memoryStream, obj);
var data = memoryStream.ToArray();
return data;
}
}
catch (SerializationException ex)
{
throw ex;
}
}
/// <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
#region stringGet
/// <summary>
/// 设置key,并保存字符串(如果key 已存在,则覆盖)
/// </summary>
/// <param name="redisKey"></param>
/// <param name="redisValue"></param>
/// <param name="expried"></param>
/// <returns></returns>
public bool StringSet(string redisKey, string redisValue, TimeSpan? expried = null)
{
redisKey = AddKeyPrefix(redisKey);
return _db.StringSet(redisKey, redisValue, expried);
}
/// <summary>
/// 保存多个key-value
/// </summary>
/// <param name="keyValuePairs"></param>
/// <returns></returns>
public bool StringSet(IEnumerable<KeyValuePair<RedisKey, RedisValue>> keyValuePairs)
{
keyValuePairs =
keyValuePairs.Select(x => new KeyValuePair<RedisKey, RedisValue>(AddKeyPrefix(x.Key), x.Value));
return _db.StringSet(keyValuePairs.ToArray());
}
/// <summary>
/// 获取字符串
/// </summary>
/// <param name="redisKey"></param>
/// <param name="expired"></param>
/// <returns></returns>
public string StringGet(string redisKey, TimeSpan? expired = null)
{
try
{
redisKey = AddKeyPrefix(redisKey);
return _db.StringGet(redisKey);
}
catch (TypeAccessException ex)
{
throw ex;
}
}
/// <summary>
/// 存储一个对象,该对象会被序列化存储
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="redisKey"></param>
/// <param name="redisValue"></param>
/// <param name="expired"></param>
/// <returns></returns>
public bool StringSet<T>(string redisKey, T redisValue, TimeSpan? expired = null)
{
redisKey = AddKeyPrefix(redisKey);
var json = Serialize(redisValue);
return _db.StringSet(redisKey, json, expired);
}
/// <summary>
/// 获取一个对象(会进行反序列化)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="redisKey"></param>
/// <param name="expired"></param>
/// <returns></returns>
public T StringSet<T>(string redisKey, TimeSpan? expired = null)
{
redisKey = AddKeyPrefix(redisKey);
return Deserialize<T>(_db.StringGet(redisKey));
}
/// <summary>
/// 保存一个字符串值
/// </summary>
/// <param name="redisKey"></param>
/// <param name="redisValue"></param>
/// <param name="expired"></param>
/// <returns></returns>
public async Task<bool> StringSetAsync(string redisKey, string redisValue, TimeSpan? expired = null)
{
redisKey = AddKeyPrefix(redisKey);
return await _db.StringSetAsync(redisKey, redisValue, expired);
}
/// <summary>
/// 保存一个字符串值
/// </summary>
/// <param name="keyValuePairs"></param>
/// <returns></returns>
public async Task<bool> StringSetAsync(IEnumerable<KeyValuePair<RedisKey, RedisValue>> keyValuePairs)
{
keyValuePairs
= keyValuePairs.Select(x => new KeyValuePair<RedisKey, RedisValue>(AddKeyPrefix(x.Key), x.Value));
return await _db.StringSetAsync(keyValuePairs.ToArray());
}
//
RedisHelper
最新推荐文章于 2023-12-11 16:15:46 发布