.NET6 WebApi开发练习—Redis缓存
Redis用的是我电脑本地安装的来做测试,这篇随笔不涉及Redis安装啦。
涉及的Nuget包:StackExchange.Redis
1、先写了一个简单的接口文件,ICache;用来学习更多中缓存方法,代码如下:
public interface ICache
{
/// <summary>
/// 设置缓存
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <param name="value"></param>
/// <param name="expireTime"></param>
/// <returns></returns>
bool SetCache<T>(string key, T value, DateTime? expireTime = null);
/// <summary>
/// 获取缓存
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="key"></param>
/// <returns></returns>
T GetCache<T>(string key);
/// <summary>
/// 根据键精准删除
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
bool RemoveCache(string key);
/// <summary>
/// 模糊删除,左侧匹配,右侧模糊
/// </summary>
/// <param name="keywords"></param>
/// <returns></returns>
Task RemoveKeysLeftLike(string keywords);
/// <summary>
/// 获取自增id
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
long GetIncr(string key);
/// <summary>
/// 获取自增id
/// </summary>
/// <param name="key">键</param>
/// <param name="expiresTime">过期时间</param>
/// <returns></returns>
long GetIncr(string key, TimeSpan expiresTime);
#region Hash
int SetHashFieldCache<T>(string key, string fieldKey, T fieldValue);
int SetHashFieldCache<T>(string key, Dictionary<string, T> dict);
T GetHashFieldCache<T>(string key, string fieldKey);
Dictionary<string, T> GetHashFieldCache<T>(string key, Dictionary<string, T> dict);
Dictionary<string, T> GetHashCache<T>(string key);
List<T> GetHashToListCache<T>(string key);
bool RemoveHashFieldCache(string key, string fieldKey);
Dictionary<string, bool> RemoveHashFieldCache(string key, Dictionary<string, bool> dict);
#endregion
}
2、在appsetting.json文件中配置Redis连接配置。
"Redis": {
"host": "127.0.0.1",
"port": 6379,
"password": "12345",
"maxWritePoolSize": 60,
"maxReadPoolSize": 60,
"autoStart": true,
"localCacheTime": 36000,
"recordeLog": false,
"preName": "flower_"
},
3、创建RedisCache.cs,实现ICache接口文件,代码如下:
public class RedisCache : ICache
{
private StackExchange.Redis.IDatabase cache;
private ConnectionMultiplexer connection;
private readonly IConfiguration _configuration;
public RedisCache(IConfiguration configuration)
{
//把appsetting.json中配置的Redis连接配置注入进来,连接Redis
_configuration = configuration;
string redisHost = _configuration["Redis:host"];
int redisPort = int.Parse(_configuration["Redis:port"]);
var configurationOptions = new ConfigurationOptions
{
EndPoints =
{
{ redisHost, redisPort }
},
KeepAlive = 180,
Password = _configuration["Redis:password"],
AllowAdmin = true
};
connection = ConnectionMultiplexer.Connect(configurationOptions);
cache = connection.GetDatabase();
}
public bool SetCache<T>(string key, T value, DateTime? expireTime = null)
{
try
{
var jsonOption = new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
string strValue = JsonConvert.SerializeObject(value, jsonOption);
if (string.IsNullOrEmpty(strValue))
{
return false;
}
if (expireTime == null)
{
return cache.StringSet(InitKey(key), strValue);
}
else
{
return cache.StringSet(InitKey(key), strValue, (expireTime.Value - DateTime.Now));
}
}
catch (Exception ex)
{
//LogHelper.Error(ex);
}
return false;
}
public bool RemoveCache(string key)
{
return cache.KeyDelete(InitKey(key));
}
public T GetCache<T>(string key)
{
var t = default(T);
try
{
var value = cache.StringGet(InitKey(key));
if (string.IsNullOrEmpty(value))
{
return t;
}
t = JsonConvert.DeserializeObject<T>(value);
}
catch (Exception ex)
{
//LogHelper.Error(ex);
}
return t;
}
public long GetIncr(string key)
{
try
{
return cache.StringIncrement(InitKey(key));
}
catch (Exception ex)
{
return 0;
}
}
public long GetIncr(string key, TimeSpan expiresTime)
{
try
{
var qty = cache.StringIncrement(InitKey(key));
if (qty == 1)
{
//设置过期时间
cache.KeyExpire(key, expiresTime);
}
return qty;
}
catch (Exception ex)
{
return 0;
}
}
#region Hash
public int SetHashFieldCache<T>(string key, string fieldKey, T fieldValue)
{
return SetHashFieldCache<T>(InitKey(key), new Dictionary<string, T> { { fieldKey, fieldValue } });
}
public int SetHashFieldCache<T>(string key, Dictionary<string, T> dict)
{
int count = 0;
var jsonOption = new JsonSerializerSettings()
{
ReferenceLoopHandling = ReferenceLoopHandling.Ignore
};
foreach (string fieldKey in dict.Keys)
{
string fieldValue = JsonConvert.SerializeObject(dict[fieldKey], jsonOption);
count += cache.HashSet(InitKey(key), fieldKey, fieldValue) ? 1 : 0;
}
return count;
}
public T GetHashFieldCache<T>(string key, string fieldKey)
{
var dict = GetHashFieldCache<T>(InitKey(key), new Dictionary<string, T> { { fieldKey, default(T) } });
return dict[fieldKey];
}
public Dictionary<string, T> GetHashFieldCache<T>(string key, Dictionary<string, T> dict)
{
foreach (string fieldKey in dict.Keys)
{
string fieldValue = cache.HashGet(InitKey(key), fieldKey);
dict[fieldKey] = JsonConvert.DeserializeObject<T>(fieldValue);
}
return dict;
}
public Dictionary<string, T> GetHashCache<T>(string key)
{
Dictionary<string, T> dict = new Dictionary<string, T>();
var hashFields = cache.HashGetAll(InitKey(key));
foreach (HashEntry field in hashFields)
{
dict[field.Name] = JsonConvert.DeserializeObject<T>(field.Value);
}
return dict;
}
public List<T> GetHashToListCache<T>(string key)
{
List<T> list = new List<T>();
var hashFields = cache.HashGetAll(InitKey(key));
foreach (HashEntry field in hashFields)
{
list.Add(JsonConvert.DeserializeObject<T>(field.Value));
}
return list;
}
public bool RemoveHashFieldCache(string key, string fieldKey)
{
Dictionary<string, bool> dict = new Dictionary<string, bool> { { fieldKey, false } };
dict = RemoveHashFieldCache(InitKey(key), dict);
return dict[fieldKey];
}
public Dictionary<string, bool> RemoveHashFieldCache(string key, Dictionary<string, bool> dict)
{
foreach (string fieldKey in dict.Keys)
{
dict[fieldKey] = cache.HashDelete(InitKey(key), fieldKey);
}
return dict;
}
private string InitKey(string key)
{
return $"{_configuration["Redis:preName"]}{key}";
}
#endregion
public void Dispose()
{
if (connection != null)
{
connection.Close();
}
GC.SuppressFinalize(this);
}
public void tet()
{
var pattern = "BUIK_201710*";
var redisResult = cache.ScriptEvaluateAsync(LuaScript.Prepare(
//Redis的keys模糊查询:
" local res = redis.call('KEYS', @keypattern) " +
" return res "), new { @keypattern = pattern }).Result;
if (!redisResult.IsNull)
{
cache.KeyDelete((RedisKey[])redisResult); //删除一组key
}
}
public async Task RemoveKeysLeftLike(string keywords)
{
var redisResult = await cache.ScriptEvaluateAsync(LuaScript.Prepare(
//Redis的keys模糊查询:
" local res = redis.call('KEYS', @keywords) " +
" return res "), new { @keywords = $"{InitKey(keywords)}*" });
if (!redisResult.IsNull)
{
cache.KeyDelete((RedisKey[])redisResult); //删除一组key
}
}
}
4、在program.cs文件中,将Redis配置注入好
//注入Redis
builder.Services.AddSingleton<ICache,RedisCache> ();
5、用法就是上篇随笔记的内容,通过构造函数注入来使用。
//存入Redis中
_redisCache.SetCache<string>($"verificationcode_{verificationCodeId}", strValidateCode, DateTime.Now.AddMinutes(5));
运行测试代码之后,通过控制台正常查到记录的数据了,算是使用成功了。