招聘后台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

634 lines
19 KiB

using Microsoft.Extensions.Caching.StackExchangeRedis;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace Znyc.Recruitment.Admin.Commons.Cache
{
/// <summary>
/// Redis缓存操作
/// </summary>
public class RedisCacheService : ICacheService
{
/// <summary>
/// </summary>
private readonly ConnectionMultiplexer _connection;
/// <summary>
/// </summary>
private readonly string _instance;
private readonly JsonSerializerOptions _jsonOptions;
/// <summary>
/// </summary>
protected IDatabase _cache;
/// <summary>
/// </summary>
/// <param name="options"></param>
/// <param name="database"></param>
/// <param name="jsonOptions"></param>
public RedisCacheService(RedisCacheOptions options, JsonSerializerOptions jsonOptions, int database = 0)
{
_connection = ConnectionMultiplexer.Connect(options.Configuration);
_cache = _connection.GetDatabase(database);
_instance = options.InstanceName;
_jsonOptions = jsonOptions;
}
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public string GetKeyForRedis(string key)
{
return _instance + key;
}
public void Dispose()
{
if (_connection != null)
{
_connection.Dispose();
}
GC.SuppressFinalize(this);
}
#region 验证缓存项是否存在
/// <summary>
/// 验证缓存项是否存在
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public bool Exists(string key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.KeyExists(GetKeyForRedis(key));
}
/// <summary>
/// 验证缓存项是否存在
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public Task<bool> ExistsAsync(string key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.KeyExistsAsync(GetKeyForRedis(key));
}
#endregion 验证缓存项是否存在
#region 添加缓存
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <returns></returns>
public bool Add(string key, object value)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.StringSet(GetKeyForRedis(key),
Encoding.UTF8.GetBytes(JsonSerializer.Serialize(value, _jsonOptions)));
}
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间,Redis中无效)</param>
/// <param name="expiressAbsoulte">绝对过期时长</param>
/// <returns></returns>
public bool Add(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.StringSet(GetKeyForRedis(key),
Encoding.UTF8.GetBytes(JsonSerializer.Serialize(value, _jsonOptions)), expiressAbsoulte);
}
/// <summary>
/// 添加缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">缓存Value</param>
/// <param name="expiresIn">缓存时长</param>
/// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间,Redis中无效)</param>
/// <returns></returns>
public bool Add(string key, object value, TimeSpan expiresIn, bool isSliding = false)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.StringSet(GetKeyForRedis(key),
Encoding.UTF8.GetBytes(JsonSerializer.Serialize(value, _jsonOptions)), expiresIn);
}
public Task<bool> AddAsync(string key, object value)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.StringSetAsync(GetKeyForRedis(key),
Encoding.UTF8.GetBytes(JsonSerializer.Serialize(value, _jsonOptions)));
}
public Task<bool> AddAsync(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.StringSetAsync(GetKeyForRedis(key),
Encoding.UTF8.GetBytes(JsonSerializer.Serialize(value, _jsonOptions)), expiressAbsoulte);
}
public Task<bool> AddAsync(string key, object value, TimeSpan expiresIn, bool isSliding = false)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.StringSetAsync(GetKeyForRedis(key),
Encoding.UTF8.GetBytes(JsonSerializer.Serialize(value, _jsonOptions)), expiresIn);
}
public Task<bool> HashSetAsync(string key, string filed, object value)
{
return _cache.HashSetAsync(GetKeyForRedis(key),
Encoding.UTF8.GetBytes(JsonSerializer.Serialize(filed, _jsonOptions)),
Encoding.UTF8.GetBytes(JsonSerializer.Serialize(value, _jsonOptions)));
}
#endregion 添加缓存
#region 删除缓存
/// <summary>
/// 删除缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public bool Remove(string key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.KeyDelete(GetKeyForRedis(key));
}
/// <summary>
/// 批量删除缓存
/// </summary>
/// <param name="key">缓存Key集合</param>
/// <returns></returns>
public void RemoveAll(IEnumerable<string> keys)
{
if (keys == null)
{
throw new ArgumentNullException(nameof(keys));
}
keys.ToList().ForEach(item => Remove(item));
}
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public Task<bool> RemoveAsync(string key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
return _cache.KeyDeleteAsync(GetKeyForRedis(key));
}
public Task RemoveAllAsync(IEnumerable<int> keys)
{
//if (keys == null)
//{
throw new ArgumentNullException(nameof(keys));
//}
//keys.ToList().ForEach(item => RemoveAsync(item));
}
/// <summary>
/// 使用通配符找出所有的key然后逐个删除
/// </summary>
/// <param name="pattern">通配符</param>
public virtual void RemoveByPattern(string pattern)
{
foreach (System.Net.EndPoint ep in _connection.GetEndPoints())
{
IServer server = _connection.GetServer(ep);
IEnumerable<RedisKey> keys = server.Keys(pattern: "*" + pattern + "*", database: _cache.Database);
foreach (RedisKey key in keys)
{
_cache.KeyDelete(key);
}
}
}
/// <summary>
/// 删除所有缓存
/// </summary>
public void RemoveCacheAll()
{
RemoveByPattern("");
}
#endregion 删除缓存
#region 获取缓存
/// <summary>
/// 获取缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public T Get<T>(string key) where T : class
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
RedisValue value = _cache.StringGet(GetKeyForRedis(key));
if (!value.HasValue)
{
return default;
}
return JsonSerializer.Deserialize<T>(value, _jsonOptions);
}
/// <summary>
/// 获取缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <returns></returns>
public object Get(string key)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
RedisValue value = _cache.StringGet(GetKeyForRedis(key));
if (!value.HasValue)
{
return null;
}
return JsonSerializer.Deserialize<object>(value, _jsonOptions);
//string json = value.ToString();
//return Newtonsoft.Json.JsonConvert.DeserializeObject(json);
}
/// <summary>
/// 获取缓存集合
/// </summary>
/// <param name="keys">缓存Key集合</param>
/// <returns></returns>
public IDictionary<string, object> GetAll(IEnumerable<string> keys)
{
if (keys == null)
{
throw new ArgumentNullException(nameof(keys));
}
Dictionary<string, object> dict = new Dictionary<string, object>();
keys.ToList().ForEach(item => dict.Add(item, Get(GetKeyForRedis(item))));
return dict;
}
public Task<T> GetAsync<T>(string key) where T : class
{
throw new NotImplementedException();
}
public Task<object> GetAsync(string key)
{
throw new NotImplementedException();
}
public Task<IDictionary<string, object>> GetAllAsync(IEnumerable<int> keys)
{
throw new ArgumentNullException(nameof(keys));
}
#endregion 获取缓存
#region 修改缓存
/// <summary>
/// 修改缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">新的缓存Value</param>
/// <returns></returns>
public bool Replace(string key, object value)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
if (Exists(key))
{
if (!Remove(key))
{
return false;
}
}
return Add(key, value);
}
/// <summary>
/// 修改缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">新的缓存Value</param>
/// <param name="expiresSliding">滑动过期时长(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
/// <param name="expiressAbsoulte">绝对过期时长</param>
/// <returns></returns>
public bool Replace(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
if (Exists(key))
{
if (!Remove(key))
{
return false;
}
}
return Add(key, value, expiresSliding, expiressAbsoulte);
}
/// <summary>
/// 修改缓存
/// </summary>
/// <param name="key">缓存Key</param>
/// <param name="value">新的缓存Value</param>
/// <param name="expiresIn">缓存时长</param>
/// <param name="isSliding">是否滑动过期(如果在过期时间内有操作,则以当前时间点延长过期时间)</param>
/// <returns></returns>
public bool Replace(string key, object value, TimeSpan expiresIn, bool isSliding = false)
{
if (key == null)
{
throw new ArgumentNullException(nameof(key));
}
if (Exists(key))
{
if (!Remove(key))
{
return false;
}
}
return Add(key, value, expiresIn, isSliding);
}
public Task<bool> ReplaceAsync(string key, object value)
{
throw new NotImplementedException();
}
public Task<bool> ReplaceAsync(string key, object value, TimeSpan expiresSliding, TimeSpan expiressAbsoulte)
{
throw new NotImplementedException();
}
public Task<bool> ReplaceAsync(string key, object value, TimeSpan expiresIn, bool isSliding = false)
{
throw new NotImplementedException();
}
#endregion 修改缓存
#region Hash
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <param name="filed"></param>
/// <param name="value"></param>
/// <returns></returns>
public bool HSet(string key, string filed, object value)
{
return RedisHelper.HSet(key, filed, value);
}
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <param name="filed"></param>
/// <param name="value"></param>
/// <returns></returns>
public Task<bool> HSetAsync(string key, string filed, object value)
{
return RedisHelper.HSetAsync(key, filed, value);
}
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public Task<bool> HMSetAsync(string key, object[] value)
{
return RedisHelper.HMSetAsync(key, value);
}
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <param name="value"></param>
/// <returns></returns>
public bool HMSet(string key, object[] value)
{
return RedisHelper.HMSet(key, value);
}
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <param name="filed"></param>
/// <returns></returns>
public string[] HMGet(string key, string[] filed)
{
return RedisHelper.HMGet(key, filed);
}
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <param name="filed"></param>
/// <returns></returns>
public Task<string[]> HMGetAsync(string key, string filed)
{
return RedisHelper.HMGetAsync(key, filed);
}
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <param name="filed"></param>
/// <returns></returns>
public long HDel(string key, string[] filed)
{
return RedisHelper.HDel(key, filed);
}
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <param name="filed"></param>
/// <returns></returns>
public Task<long> HDelAsync(string key, string filed)
{
return RedisHelper.HDelAsync(key, filed);
}
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <param name="filed"></param>
/// <returns></returns>
public bool HExists(string key, string filed)
{
return RedisHelper.HExists(key, filed);
}
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <param name="filed"></param>
/// <returns></returns>
public Task<bool> HExistsAsync(string key, string filed)
{
return RedisHelper.HExistsAsync(key, filed);
}
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <param name="filed"></param>
/// <returns></returns>
public Task<long> HIncrByAsync(string key, string filed)
{
return RedisHelper.HIncrByAsync(key, filed);
}
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <param name="filed"></param>
/// <returns></returns>
public long HIncrBy(string key, string filed)
{
return RedisHelper.HIncrBy(key, filed);
}
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public Task<Dictionary<string, string>> HGetAllAsync(string key)
{
return RedisHelper.HGetAllAsync(key);
}
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public Dictionary<string, string> HGetAll(string key)
{
return RedisHelper.HGetAll(key);
}
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <param name="filed"></param>
/// <returns></returns>
public async Task<string> HGetAsync(string key, string filed)
{
return await RedisHelper.HGetAsync(key, filed);
}
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <param name="filed"></param>
/// <param name="value"></param>
/// <returns></returns>
public Task<bool> HSetNxAsync(string key, string filed, object value)
{
return RedisHelper.HSetNxAsync(key, filed, value);
}
/// <summary>
/// </summary>
/// <param name="key"></param>
/// <param name="filed"></param>
/// <param name="value"></param>
/// <returns></returns>
public bool HSetNx(string key, string filed, object value)
{
return RedisHelper.HSetNx(key, filed, value);
}
#endregion Hash
}
}