<<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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...