Asp.Net Core基于StackExchange Redis 缓存

NuGet安装

StackExchange.Redis

Microsoft.Extensions.Options

0. appsettings.json初始化配置

javascript 复制代码
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "Redis": {
    "ConnectionString": "localhost:6379",
    "InstanceName": "anna_",
    "DefaultDatabase": 5,
    "ConnectRetry": 3,
    "ConnectTimeout": 5000,
    "AbortOnConnectFail": false
  },
  "ConnectionStrings": {
    "default": "Host=10.10.11.185;Port=5432;Database=KSJGOM2DB;Username=postgres;Password=money13;"
  }
}

1.Redis初始化对象

cs 复制代码
/// <summary>
/// Redis初始化对象
/// </summary>
public class RedisOptions
{
    public const string Redis = "Redis";

    public string ConnectionString { get; set; }
    public string InstanceName { get; set; }
    public int DefaultDatabase { get; set; } = 0;
    public int ConnectRetry { get; set; } = 3;
    public int ConnectTimeout { get; set; } = 5000;
    public bool AbortOnConnectFail { get; set; } = false;
}

2.接口

cs 复制代码
public interface IRedisService
{
    #region String 操作
    Task<bool> StringSetAsync<T>(string key, T value, TimeSpan? expiry = null);
    Task<T> StringGetAsync<T>(string key);
    Task<long> StringIncrementAsync(string key, long value = 1);
    Task<long> StringDecrementAsync(string key, long value = 1);
    #endregion

    #region Hash 操作
    Task<bool> HashSetAsync<T>(string hashKey, string key, T value);
    Task<bool> HashDeleteAsync(string hashKey, string key);
    Task<T> HashGetAsync<T>(string hashKey, string key);
    Task<Dictionary<string, T>> HashGetAllAsync<T>(string hashKey);
    Task<long> HashLengthAsync(string hashKey);
    #endregion

    #region List 操作
    Task<long> ListLeftPushAsync<T>(string key, T value);
    Task<long> ListRightPushAsync<T>(string key, T value);
    Task<T> ListLeftPopAsync<T>(string key);
    Task<T> ListRightPopAsync<T>(string key);
    Task<long> ListLengthAsync(string key);
    Task<IEnumerable<T>> ListRangeAsync<T>(string key, long start = 0, long stop = -1);
    #endregion

    #region Set 操作
    Task<bool> SetAddAsync<T>(string key, T value);
    Task<bool> SetRemoveAsync<T>(string key, T value);
    Task<bool> SetContainsAsync<T>(string key, T value);
    Task<long> SetLengthAsync(string key);
    Task<IEnumerable<T>> SetMembersAsync<T>(string key);
    #endregion

    #region SortedSet 操作
    Task<bool> SortedSetAddAsync<T>(string key, T value, double score);
    Task<bool> SortedSetRemoveAsync<T>(string key, T value);
    Task<double?> SortedSetScoreAsync<T>(string key, T value);
    Task<long> SortedSetLengthAsync(string key);
    Task<IEnumerable<T>> SortedSetRangeByRankAsync<T>(string key, long start = 0, long stop = -1, Order order = Order.Ascending);
    Task<IEnumerable<T>> SortedSetRangeByScoreAsync<T>(string key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Order order = Order.Ascending);
    #endregion

    #region 通用操作
    Task<bool> KeyDeleteAsync(string key);
    Task<bool> KeyExistsAsync(string key);
    Task<bool> KeyExpireAsync(string key, TimeSpan? expiry);
    Task<TimeSpan?> KeyTimeToLiveAsync(string key);
    #endregion
}

3. 实现

cs 复制代码
public class RedisService : IRedisService, IDisposable
{
    private readonly IConnectionMultiplexer _redis;
    private readonly RedisOptions _options;
    private readonly IDatabase _database;
    private readonly JsonSerializerOptions _jsonOptions;

    public RedisService(IOptions<RedisOptions> optionsAccessor)
    {
        _options = optionsAccessor.Value;
        _jsonOptions = new JsonSerializerOptions
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            WriteIndented = false
        };

        var config = ConfigurationOptions.Parse(_options.ConnectionString);
        config.AbortOnConnectFail = _options.AbortOnConnectFail;
        config.ConnectRetry = _options.ConnectRetry;
        config.ConnectTimeout = _options.ConnectTimeout;

        _redis = ConnectionMultiplexer.Connect(config);
        _database = _redis.GetDatabase(_options.DefaultDatabase);
    }

    private string GetPrefixedKey(string key) => $"{_options.InstanceName}{key}";

    #region String 操作实现
    public async Task<bool> StringSetAsync<T>(string key, T value, TimeSpan? expiry = null)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.StringSetAsync(GetPrefixedKey(key), json, expiry);
    }

    public async Task<T> StringGetAsync<T>(string key)
    {
        var value = await _database.StringGetAsync(GetPrefixedKey(key));
        return value.HasValue ? JsonSerializer.Deserialize<T>(value, _jsonOptions) : default;
    }

    public async Task<long> StringIncrementAsync(string key, long value = 1)
    {
        return await _database.StringIncrementAsync(GetPrefixedKey(key), value);
    }

    public async Task<long> StringDecrementAsync(string key, long value = 1)
    {
        return await _database.StringDecrementAsync(GetPrefixedKey(key), value);
    }
    #endregion

    #region Hash 操作实现
    public async Task<bool> HashSetAsync<T>(string hashKey, string key, T value)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.HashSetAsync(GetPrefixedKey(hashKey), key, json);
    }

    public async Task<bool> HashDeleteAsync(string hashKey, string key)
    {
        return await _database.HashDeleteAsync(GetPrefixedKey(hashKey), key);
    }

    public async Task<T> HashGetAsync<T>(string hashKey, string key)
    {
        var value = await _database.HashGetAsync(GetPrefixedKey(hashKey), key);
        return value.HasValue ? JsonSerializer.Deserialize<T>(value, _jsonOptions) : default;
    }

    public async Task<Dictionary<string, T>> HashGetAllAsync<T>(string hashKey)
    {
        var entries = await _database.HashGetAllAsync(GetPrefixedKey(hashKey));
        return entries.ToDictionary(
            x => x.Name.ToString(),
            x => JsonSerializer.Deserialize<T>(x.Value, _jsonOptions));
    }

    public async Task<long> HashLengthAsync(string hashKey)
    {
        return await _database.HashLengthAsync(GetPrefixedKey(hashKey));
    }
    #endregion

    #region List 操作实现
    public async Task<long> ListLeftPushAsync<T>(string key, T value)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.ListLeftPushAsync(GetPrefixedKey(key), json);
    }

    public async Task<long> ListRightPushAsync<T>(string key, T value)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.ListRightPushAsync(GetPrefixedKey(key), json);
    }

    public async Task<T> ListLeftPopAsync<T>(string key)
    {
        var value = await _database.ListLeftPopAsync(GetPrefixedKey(key));
        return value.HasValue ? JsonSerializer.Deserialize<T>(value, _jsonOptions) : default;
    }

    public async Task<T> ListRightPopAsync<T>(string key)
    {
        var value = await _database.ListRightPopAsync(GetPrefixedKey(key));
        return value.HasValue ? JsonSerializer.Deserialize<T>(value, _jsonOptions) : default;
    }

    public async Task<long> ListLengthAsync(string key)
    {
        return await _database.ListLengthAsync(GetPrefixedKey(key));
    }

    public async Task<IEnumerable<T>> ListRangeAsync<T>(string key, long start = 0, long stop = -1)
    {
        var values = await _database.ListRangeAsync(GetPrefixedKey(key), start, stop);
        return values.Select(v => JsonSerializer.Deserialize<T>(v, _jsonOptions));
    }
    #endregion

    #region Set 操作实现
    public async Task<bool> SetAddAsync<T>(string key, T value)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.SetAddAsync(GetPrefixedKey(key), json);
    }

    public async Task<bool> SetRemoveAsync<T>(string key, T value)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.SetRemoveAsync(GetPrefixedKey(key), json);
    }

    public async Task<bool> SetContainsAsync<T>(string key, T value)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.SetContainsAsync(GetPrefixedKey(key), json);
    }

    public async Task<long> SetLengthAsync(string key)
    {
        return await _database.SetLengthAsync(GetPrefixedKey(key));
    }

    public async Task<IEnumerable<T>> SetMembersAsync<T>(string key)
    {
        var values = await _database.SetMembersAsync(GetPrefixedKey(key));
        return values.Select(v => JsonSerializer.Deserialize<T>(v, _jsonOptions));
    }
    #endregion

    #region SortedSet 操作实现
    public async Task<bool> SortedSetAddAsync<T>(string key, T value, double score)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.SortedSetAddAsync(GetPrefixedKey(key), json, score);
    }

    public async Task<bool> SortedSetRemoveAsync<T>(string key, T value)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.SortedSetRemoveAsync(GetPrefixedKey(key), json);
    }

    public async Task<double?> SortedSetScoreAsync<T>(string key, T value)
    {
        var json = JsonSerializer.Serialize(value, _jsonOptions);
        return await _database.SortedSetScoreAsync(GetPrefixedKey(key), json);
    }

    public async Task<long> SortedSetLengthAsync(string key)
    {
        return await _database.SortedSetLengthAsync(GetPrefixedKey(key));
    }

    public async Task<IEnumerable<T>> SortedSetRangeByRankAsync<T>(string key, long start = 0, long stop = -1, Order order = Order.Ascending)
    {
        var values = await _database.SortedSetRangeByRankAsync(GetPrefixedKey(key), start, stop, order);
        return values.Select(v => JsonSerializer.Deserialize<T>(v, _jsonOptions));
    }

    public async Task<IEnumerable<T>> SortedSetRangeByScoreAsync<T>(string key, double start = double.NegativeInfinity, double stop = double.PositiveInfinity, Order order = Order.Ascending)
    {
        var values = await _database.SortedSetRangeByScoreAsync(GetPrefixedKey(key), start, stop, order: order);
        return values.Select(v => JsonSerializer.Deserialize<T>(v, _jsonOptions));
    }
    #endregion

    #region 通用操作实现
    public async Task<bool> KeyDeleteAsync(string key)
    {
        return await _database.KeyDeleteAsync(GetPrefixedKey(key));
    }

    public async Task<bool> KeyExistsAsync(string key)
    {
        return await _database.KeyExistsAsync(GetPrefixedKey(key));
    }

    public async Task<bool> KeyExpireAsync(string key, TimeSpan? expiry)
    {
        return await _database.KeyExpireAsync(GetPrefixedKey(key), expiry);
    }

    public async Task<TimeSpan?> KeyTimeToLiveAsync(string key)
    {
        return await _database.KeyTimeToLiveAsync(GetPrefixedKey(key));
    }
    #endregion

    public void Dispose()
    {
        _redis?.Dispose();
    }
}

4.依赖注入

Program.cs中添加如下代码:

cs 复制代码
 // 配置Redis选项
 builder.Services.Configure<RedisOptions>(builder.Configuration.GetSection(RedisOptions.Redis));
 // 注册Redis服务
 builder.Services.AddSingleton<IRedisService, RedisService>();

5.控制器中使用

cs 复制代码
public class TestController : ControllerBase
{
    private readonly IRedisService _redis;
    private readonly IUserService _userService;
    public TestController(IRedisService redis, IUserService userService) 
    {
        _redis = redis;
        _userService = userService;
    }

    [HttpGet("string")]
    public async Task<IActionResult> TestString()
    {
        var user = await _userService.GetCurrentUserAsync();

        Console.WriteLine(user.TrueName);

        await _redis.StringSetAsync("anna","多慢慢流");
        var result = await _redis.StringGetAsync<string>("anna");
        return Ok(result);
    }

    [HttpGet("hash")]
    public async Task<IActionResult> TestHash()
    {
        string hkey = "fdm";
        await _redis.HashSetAsync(hkey, "fd1",new {Name="annadeville",Props="运动型" });
        await _redis.HashSetAsync(hkey,"fd2",new { Name="RR",Props="皮"});
        
        var all= await _redis.HashGetAllAsync<dynamic>(hkey);
        var fd1 = await _redis.HashGetAsync<dynamic>(hkey, "fd1");
        return Ok(new { All = all, Field1 = fd1 });
    }

}
相关推荐
潘yi.11 分钟前
NoSQL之Redis配置与优化
数据库·redis·nosql
伤不起bb16 分钟前
NoSQL 之 Redis 配置与优化
linux·运维·数据库·redis·nosql
半桔1 小时前
【Linux手册】冯诺依曼体系结构
linux·缓存·职场和发展·系统架构
14L2 小时前
互联网大厂Java面试:从Spring Cloud到Kafka的技术考察
spring boot·redis·spring cloud·kafka·jwt·oauth2·java面试
一个有女朋友的程序员2 小时前
Spring Boot 缓存注解详解:@Cacheable、@CachePut、@CacheEvict(超详细实战版)
spring boot·redis·缓存
yuren_xia3 小时前
在Spring Boot中集成Redis进行缓存
spring boot·redis·缓存
愿你是阳光06075 小时前
Java-redis实现限时在线秒杀功能
java·redis·bootstrap
John Song5 小时前
macOS 上使用 Homebrew 安装redis-cli
数据库·redis·macos
数据知道5 小时前
Mac电脑上本地安装 redis并配置开启自启完整流程
数据库·redis·macos
Lonely丶墨轩5 小时前
Redis 缓存策略:借助缓存优化数据库性能并保障数据一致性
数据库·redis·缓存