循序渐进学.Net Core Web Api开发系列【12】:缓存

原文:循序渐进学.Net Core Web Api开发系列【12】:缓存

系列目录

循序渐进学.Net Core Web Api开发系列目录

 本系列涉及到的源码下载地址:https://github.com/seabluescn/Blog_WebApi

一、概述

本篇介绍如何使用缓存,包括MemeryCache和Redis。

二、MemeryCache

1、注册缓存服务

  public void ConfigureServices(IServiceCollection services)
   {
            services.AddMemoryCache();   
  }

貌似较新的版本是默认已经注册缓存服务的,以上代码可以省略,不过加一下也没有问题。

2、在Controller中注入依赖

复制代码
public class ArticleController : Controller
{
        private readonly IMemoryCache _cache;
    </span><span style="color: #0000ff;">public</span> ArticleController(SalesContext context, ILogger&lt;ArticleController&gt;<span style="color: #000000;"> logger, IMemoryCache memoryCache)
    {
        _cache </span>=<span style="color: #000000;"> memoryCache;
    }

}

复制代码

3、基本使用方法

复制代码
public List<Article> GetAllArticles()
        {           
            List<Article> articles = null;
        </span><span style="color: #0000ff;">if</span> (!_cache.<span style="color: #ff00ff;">TryGetValue</span>&lt;List&lt;Article&gt;&gt;(<span style="color: #800000;">"</span><span style="color: #800000;">GetAllArticles</span><span style="color: #800000;">"</span>, <span style="color: #0000ff;">out</span><span style="color: #000000;"> articles))            
        {
            _logger.LogInformation(</span><span style="color: #800000;">"</span><span style="color: #800000;">未找到缓存,去数据库查询</span><span style="color: #800000;">"</span><span style="color: #000000;">);

            articles </span>=<span style="color: #000000;"> _context.Articles
                .AsNoTracking()
                .ToList</span>&lt;Article&gt;<span style="color: #000000;">();

            _cache.<span style="color: #ff00ff;">Set</span>(</span><span style="color: #800000;">"</span><span style="color: #800000;">GetAllArticles</span><span style="color: #800000;">"</span><span style="color: #000000;">, articles);
        }           </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> articles;
    }</span></pre>
复制代码

逻辑是这样的:

(1)、去缓存读取指定内容;(2)如果没有读取到,就去数据库区数据,并存入缓存;(3)如果取到就直接返回数据。

4、缓存的过期

绝对过期:设定时间一到就过期。适合要定期更新的场景,比如组织机构信息数据。

_cache.Set("GetAllArticles", articles, 
new MemoryCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromSeconds(20)));

相对过期:距离最后一次使用(TryGetValue)后指定时间后过期,比如用户登陆信息。

_cache.Set("GetAllArticles", articles, 
new MemoryCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromSeconds(20)));

三、分布式缓存Redis的使用

1、缓存服务注册

复制代码
public void ConfigureServices(IServiceCollection services)
 {  
            services.AddDistributedRedisCache(options =>
            {               
                options.Configuration = Configuration["Redis:Configuration"];
                options.InstanceName = Configuration["Redis:InstanceName"];
            });
}
复制代码

appsettings.json的内容大致如下:

1
2
3
4
5
6
7
8
9
10
{
  "ConnectionStrings": {
    "SQLServerConnection": "....;",
    "MySQLConnection": "...;"
  }, 
  "Redis": {
    "Configuration": "IP:1987,allowAdmin=true,password=******,defaultdatabase=5",
    "InstanceName": "SaleService_"
  }
}

如果设置了的InstanceName话,所有存储的KEY会增加这个前缀。

2、在Controller中引入依赖

复制代码
    [Produces("application/json")]
    [Route("api/Article")]
    public class ArticleController : Controller
    {      private readonly IDistributedCache _distributedCache;
    </span><span style="color: #0000ff;">public</span> ArticleController(<span style="color: #000000;">IDistributedCache distributedCache)
    {</span><span style="color: #000000;">
        _distributedCache </span>=<span style="color: #000000;"> distributedCache;
    }

}

复制代码

3、基本使用

复制代码
       [HttpGet("redis")]
        public void TestRedis()
        {           
            String tockenid = "AAAaaa";       
            string infostr =  _distributedCache.GetString(tockenid);
        </span><span style="color: #0000ff;">if</span>(infostr == <span style="color: #0000ff;">null</span><span style="color: #000000;">)
        {
            _logger.LogInformation(</span><span style="color: #800000;">"</span><span style="color: #800000;">未找到缓存,写入Redis</span><span style="color: #800000;">"</span><span style="color: #000000;">);                               
            _distributedCache.SetString(tockenid, </span><span style="color: #800000;">"</span><span style="color: #800000;">hello,0601</span><span style="color: #800000;">"</span><span style="color: #000000;">); 
        }
        </span><span style="color: #0000ff;">else</span><span style="color: #000000;">
        {
            _logger.LogInformation(</span><span style="color: #800000;">"</span><span style="color: #800000;">找到缓存</span><span style="color: #800000;">"</span><span style="color: #000000;">);               
            _logger.LogInformation($</span><span style="color: #800000;">"</span><span style="color: #800000;">infostr={infostr}</span><span style="color: #800000;">"</span><span style="color: #000000;">);
        }           

        </span><span style="color: #0000ff;">return</span><span style="color: #000000;">;
    }
}</span></pre>
复制代码

  

4、存储对象

由于Redis只能存储字符串,所有对于对象的存取需要进行序列化操作。

复制代码
 [HttpGet("redis_object")]
        public List<Article> TestRedis4Object()
        {           
        String objectid </span>= <span style="color: #800000;">"</span><span style="color: #800000;">articles</span><span style="color: #800000;">"</span><span style="color: #000000;">;
        List</span>&lt;Article&gt; articles = <span style="color: #0000ff;">null</span><span style="color: #000000;">;<br>
        </span><span style="color: #0000ff;">var</span> valuebytes =<span style="color: #000000;"> _distributedCache.Get(objectid);

        </span><span style="color: #0000ff;">if</span> (valuebytes == <span style="color: #0000ff;">null</span><span style="color: #000000;">)
        {
            _logger.LogInformation(</span><span style="color: #800000;">"</span><span style="color: #800000;">未找到缓存,写入Redis</span><span style="color: #800000;">"</span><span style="color: #000000;">);
            articles </span>=<span style="color: #000000;"> _context.Articles.AsNoTracking().ToList();
            </span><span style="color: #0000ff;">byte</span>[] serializedResult =<span style="color: #000000;"> Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(articles));
            _distributedCache.Set(objectid, serializedResult);
            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> articles;
        }
        </span><span style="color: #0000ff;">else</span><span style="color: #000000;">
        {
            _logger.LogInformation(</span><span style="color: #800000;">"</span><span style="color: #800000;">找到缓存</span><span style="color: #800000;">"</span><span style="color: #000000;">);
            articles </span>=JsonConvert.DeserializeObject&lt;List&lt;Article&gt;&gt;<span style="color: #000000;">(Encoding.UTF8.GetString(valuebytes));
            </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> articles;
        }          
    }</span></pre>
复制代码

5、缓存的过期

绝对过期:

_distributedCache.SetString(tockenid, "hello,0601",new DistributedCacheEntryOptions().SetAbsoluteExpiration(TimeSpan.FromSeconds(10)));

相对过期:

_distributedCache.SetString(tockenid, "hello,0601",new DistributedCacheEntryOptions().SetSlidingExpiration(TimeSpan.FromSeconds(10)));

6、客户端工具

采用Redis Desktop Manager 可以查看存储情况

原文地址:https://www.cnblogs.com/owenzh/p/11206902.html