<<ABP框架>> 緩存

来源:http://www.cnblogs.com/kid1412/archive/2016/10/22/5987083.html
-Advertisement-
Play Games

簡介 ABP提供了一個緩存介面,它內部使用了這個緩存介面。雖然介面的預設實現是MemoryCache,但可以用任何其它實現的緩存供應器。Abp.RedisCache包用Redis實現了緩存(查看下方的“Redis 緩存集成”)。 ICacheManager 緩存的主要介面是ICacheManager ...


簡介

ABP提供了一個緩存介面,它內部使用了這個緩存介面。雖然介面的預設實現是MemoryCache,但可以用任何其它實現的緩存供應器。Abp.RedisCache包用Redis實現了緩存(查看下方的“Redis 緩存集成”)。

 

ICacheManager

緩存的主要介面是ICacheManager。我們可以註入它並用它獲取一個緩存,如:

public class TestAppService : ApplicationService
{
    private readonly ICacheManager _cacheManager;

    public TestAppService(ICacheManager cacheManager)
    {
        _cacheManager = cacheManager;
    }

    public Item GetItem(int id)
    {
        //Try to get from cache
        return _cacheManager
                .GetCache("MyCache")
                .Get(id.ToString(), () => GetFromDatabase(id)) as Item;
    }

    public Item GetFromDatabase(int id)
    {
        //... retrieve item from database
    }
}

在此例里,我們註入了ICacheManager,並獲得一個名為MyCache的緩存。

警告:GetCache方法

如果你的類不是單例,不要在你構造器里使用GetCache,否則可能會銷毀你的緩存。

 

ICache

ICacheManager.GetCache方法返回一個ICache。一個緩存是單例的(每個緩存名)。第一次請求時創建,然後一直返回同一個緩存對象。所以,我們可以在不同的類(客戶端)里用相同的名字共用同一個緩存。

在示例代碼里,我們看到了ICache.get方法的簡單使用。它有兩個參數:

key:字元串,必需,一個緩存項的鍵。

factory:一個action(行為),在找不到指定key的緩存項時調用,Factory方法應該創建並返回切實的項,如果指定key的緩存已存在,就不調用。

ICache介面也有如GetOrDefault、Set、Remove和Clear等方法。同樣也有async版本。

 

ITypedCache

ICache介面以字元串為key,值是object類型。ITypedCache包裝了ICache並提供了類型安全、泛型。我們可用泛型的GetCache擴展方法,獲取一個ITypedCache:

ITypedCache<int, Item> myCache = _cacheManager.GetCache<int, Item>("MyCache");

同樣,我們也可用AsTyped擴展方法,把一個已存在的ICache實例轉換成ITypedCache。

 

配置

預設緩存超時是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個小時。

在第一次創建緩存(在第一次請求)調用你的配置行為。配置不僅限於DefaultSlidingExpireTime,由於緩存對象是一個ICache,所以你可以用它的屬性和方法,自由的配置和初始化。

 

實體緩存

雖然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里。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 入門概述 1 NoSQL是什麼? NoSQL(NoSQL = Not Only SQL ),意即“不僅僅是SQL”,泛指非關係型的資料庫。隨著互聯網web2.0網站的興起,傳統的關係資料庫在應付web2.0網站,特別是超大規模和高併發的SNS類型的web2.0純動態網站已經顯得力不從心,暴露了很多難 ...
  • JDBCday04_大對象_Dao_DBUtil_JavaBean 大對象 (一般不用) clob(海量文字,如圖書) blob(二進位數據,如圖片,音樂,電影) clob海量文字存入資料庫 : FileReader(讀文本) + PreparedStatement的setCharacterStre ...
  • 1、單機MySQL的美好年代 在90年代,一個網站的訪問量一般都不大,用單個資料庫完全可以輕鬆應付。在那個時候,更多的都是靜態網頁,動態交互類型的網站不多。 上述架構下,我們來看看數據存儲的瓶頸是什麼?1.數據量的總大小 一個機器放不下時2.數據的索引(B+ Tree)一個機器的記憶體放不下時3.訪問 ...
  • 官方說5.5開始就廢棄mysql_query()這塊東西很多,當然常用的就幾個還是看手冊吧。 這裡簡單記錄一下。在我失憶之後可以找回一點記憶。最近一直用框架原生的都快忘了。 1.打開mysql連接 $resource1 = mysql_connect('localhost', 'root', 'ro ...
  • 字元串截斷函數是指:Stuff 和 SubString,字元串查找函數是:CharIndex 和 PatIndex 一,SubString 截取子串 最常用的字元串函數,用於截取特定長度的子串。 參數說明: start 參數:整數,表示開始位置;字元的序號(index)從1開始,即第一個字元的序號是 ...
  • 今天遇到了一個問題,要查詢今天添加到一個表中的數據,後來解決了,嗯,記錄一下: SELECT * FROM 表1 WHERE convert(varchar(10),表1.創建時間,120)=CONVERT(VARCHAR(10),GETDATE(),120) 如果是本月的話: SELECT * F ...
  • Centos6.5之ssh免密碼登錄配置 centos ssh 免密碼登錄 0.說明 這裡為了方便說明問題,假設有A和B兩台安裝了centos6.5的主機。目標是實現A、B兩台主機分別能夠通過ssh免密碼登錄到對方主機。不同主機的配置過程一樣,這裡介紹A主機的配置過程。 事先在AB主機分別創建好要免 ...
  • 一、說明 安裝環境 centos6.6 (64位) python2.7.10 (升級系統預設python版本的方法參見 "在CentOS 6.5上安裝python2.7" ) 約定 工作目錄假定為當前用戶的HOME目錄 安裝的各軟體版本以文檔編寫時的最新版為基準,請結合實際情況參考。 尖括弧""包括 ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...