abp 缓存使用

官方文档地址:https://aspnetboilerplate.com/Pages/Documents/Caching

1.先set 后取出

需要在控制器中注入ICacheManager,

[Route("api/[controller]/[action]")]
    [ApiController]
    public class WeChatController : TestControllerBase
    { 

        private readonly ICacheManager _cacheManager;
        private IHttpClientFactory _httpClient;
        public WeChatController( IHttpClientFactory httpClient,   ICacheManager cacheManager)
        { 
            this._cacheManager = cacheManager;
            this._httpClient = httpClient;
        } 

        /// <summary>
        /// 获取微信ID
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<dynamic> GetWechatID(string js_code)
        {

            try
            {
                using (var client = _httpClient.CreateClient())
                {
                    var url = $"https://api.weixin.qq.com/sns/jscode2session?appid=111&secret=11&js_code={js_code}&grant_type=authorization_code";
                    //使用注入的httpclientfactory获取client

                    client.BaseAddress = new Uri(url);
                    //设置请求体中的内容,并以post的方式请求
                    var response = await client.GetAsync(url);
                    //获取请求到数据,并转化为字符串
                    var result = response.Content.ReadAsStringAsync().Result;
                    dynamic aa = JsonConvert.DeserializeObject<dynamic>(result);
                    string session_key = aa.session_key;
                    
                    string openid = aa.openid;
                    string bb = PublicMethods.Encrypt(openid);
                    _cacheManager.GetCache("微信登录").Remove(bb);//先删除之前缓存的数据
                    _cacheManager.GetCache("微信登录").Set(bb, session_key);//可以理解为定义一个表  然后写入数据 以bb为标识 session_key是要保存的数据
                    return Json(new { ok = true, msg = "sucess", data = bb });
                }

            }
            catch (Exception e)
            {
                return Json(new { ok = false, msg = "error", data = e.Message });
            }
        }
         

        /// <summary>
        /// 微信步数解密 
        /// </summary>
        /// <returns></returns>
        [HttpPost]
        public ActionResult Decrypt(T微信步数解密 Decrypt)
        {  
            string sessionKey = _cacheManager.GetCache("微信登录").GetOrDefault(Decrypt.wechatid).ToString(); //取出缓存的sessionKey 
            
                return Ok(sessionKey); 
        } 
         
    }

2.先get没有则存入数据

[Route("api/[controller]/[action]")]
    [ApiController]
    public class TablesController : TestControllerBase
    {
        private readonly ICacheManager _cacheManager;
        private string currentUserName;

        public TablesController(ICacheManager cacheManager)
        {
            _cacheManager = cacheManager;

        }
        [NonAction]
        private T医生 Get责任医生By卫生室编号InCache(string _卫生室编号)
        {
            return _cacheManager
                    .GetCache("责任医生")
                    .Get(_卫生室编号, () => Get责任医生By卫生室编号(_卫生室编号)) as T医生;

        }

        [NonAction]
        private T医生 Get责任医生By卫生室编号(string _卫生室编号)
        {
            using (IDbConnection dbConnection = DapperHelper.CreateLocalConnection())
            {
                var sql责任医生 = $@"select top 1 * 
                                    from 表_医生 where 
                                    医生类别='责任医生' and 组织机构编号='{_卫生室编号}'";

                return dbConnection.QueryFirstOrDefault<T医生>(sql责任医生);
            }
        } 

}

3.设置缓存失效时间

默认缓存超时是60分钟,它可以改。如果你超过60分钟没有使用缓存中的项,会从缓存中自动移除。你可以配置指定的缓存或是全部的缓存。

//Configuration for all caches
Configuration.Caching.ConfigureAll(cache =>
{
    cache.DefaultSlidingExpireTime = TimeSpan.FromHours(2);
});

//Configuration for a specific cache
Configuration.Caching.Configure("MyCache", cache =>
{
    cache.DefaultSlidingExpireTime = TimeSpan.FromHours(8);
});

这段代码应该写在你模块的PreInitialize方法里,用这段代码,MyCache将有8个小时的超时时间,其它的缓存有2个小时。  ***.core——***CoreModule——PreInitialize()

 

在第一次创建缓存(在第一次请求)调用你的配置行为。配置不是只有DefaultSlidingExpireTime,由于缓存对象是一个ICache,所以你可以用它的属性和方法,自由的配置和初始化。

4.实体缓存

虽然ABP缓存系统出于普通的目的,但有一个EntityCache基类,可帮你缓存实体。如果我们通过它们的Id获取的实体,我们可以用这个基类缓存它们,就不用再频繁地从数据库查询。假设我们有如下所示的一个person实体:

public class Person : Entity
{
    public string Name { get; set; }

    public int Age { get; set; }
}

并假设我们已经知道Id,要频繁地获取Name。首先,我们需要创建一个类来缓存项:

[AutoMapFrom(typeof(Person))]
public class PersonCacheItem
{
    public string Name { get; set; }
}

我们不应该直接在缓存里存储实体,由于缓存可能需要序列化缓存对象,而实体不一定能序列化(尤其有导航属性的实体)。这就是为什么我们创建一个简单(像DTO:数据传输对象)类存储数据。添加AutoMapFrom特性,它可以自动地把Person转换成PersonCacheItem对象。如果我们不使用AutoMapFrom,我们应该为重载EntityCache类的MapToCacheItem方法,手动转换/映射。

虽然不是必需,但我们可能想为我们的缓存类定义一个接口:

public interface IPersonCache : IEntityCache<PersonCacheItem>
{

}

最后,我们可以为实体创建缓存类:

public class PersonCache : EntityCache<Person, PersonCacheItem>, IPersonCache, ITransientDependency
{
    public PersonCache(ICacheManager cacheManager, IRepository<Person> repository)
        : base(cacheManager, repository)
    {

    }
}

这就是全部代码,我们的Person缓存已经可用。缓存类可以是暂时的(如示例)或单体的,这不是说缓存的数据是暂时的,它始终在你的应用里是全局的并线程安全的。

现在,任何需要Person的Name时,我们可以通过person的Id从缓存获取,使用Person缓存的示例如下:

public class MyPersonService : ITransientDependency
{
    private readonly IPersonCache _personCache;

    public MyPersonService(IPersonCache personCache)
    {
        _personCache = personCache;
    }

    public string GetPersonNameById(int id)
    {
        return _personCache[id].Name; //alternative: _personCache.Get(id).Name;
    }
}

我们简单地注入IPersonCache,获取缓存项和获取Name属性。

EntityCache 是如何工作

  • 在第一个调用里获取从仓储(从数据库)获取实体,然后在接下来的调用里从缓存里获取。
  •  如果实体更新或删除后,它自动使缓存失效,所以它将在下一个调用里重新从数据库获取。
  • 使用IObjectMapper映射到缓存项,AutoMpper模块实现了IObjectMapper,所以需要AutoMapper模块。你可以重载MapToCacheItem方法,手动映射实体到缓存项。
  • 使用缓存类全名作为缓存时的名称,你可以通过传递一个缓存名给基构造器来改变它。
  • 是线程安全的。

如果你需要更复杂的缓存技术,你可以扩展EntityCache或创建你自己的解决方案。

Redis 缓存集成

默认缓存管理使用的是内存缓存。所以,如果你有多个并发的Web服务器使用同个应用,可能会成为一个问题,在这种情况下,你需要一个分布/集中缓存服务,你就可以简单的使用Redis做为你的缓存服务器。

首先,你要在你的应用里,安装Abp.RedisCache的Nuget包(例如,你可在你的Web项目里安装)。接着为AbpRedisCacheModule添加DependsOn特性,然后在你模块预初始化方法里调用useRedis扩展方法。如下所示:

//...other namespaces
using Abp.Runtime.Caching.Redis;

namespace MyProject.AbpZeroTemplate.Web
{
    [DependsOn(
        //...other module dependencies
        typeof(AbpRedisCacheModule))]
    public class MyProjectWebModule : AbpModule
    {
        public override void PreInitialize()
        {
            //...other configurations
            
            Configuration.Caching.UseRedis();
        }
        
        //...other code
    }
}

Abp.RedisCache包使用”localhost“作为默认连接字符串,你可以在配置文件里添加连接字符串重写它,例如:

<add name="Abp.Redis.Cache" connectionString="localhost"/>

同样,你可以向appSettings里添加Redis的数据库Id,例如:

<add key="Abp.Redis.Cache.DatabaseId" value="2"/>

不同的数据库Id,在同一服务器上,帮助创建不同的键空间(独立缓存)。

UseRedis方法也有一个重载,用给定的action(行为)直接设置选项值(在配置文件中重写)。

查看更多有关Redis信息及它的配置,请查阅Redis文档

提醒:Redis服务器应该安装和运行在ABP里。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

香煎三文鱼

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值