在網站專案中,常有從資料庫讀取清單選項或對照表的需求,例如: 商品分類、請假假別...等等,這些資訊在系統中的變動頻率極低,查詢頻率很高,若每次用到都去資料庫查,是很沒效率的設計。因此我習慣將這些資料轉成List<T>或Dictionary<string, string>,保留在Cache一段時間,稍後又要使用時,統一透過特定函數存取。在該函數中有額外的智慧判斷邏輯,它先檢查Cache中是否有現成資料物件可用,若有則直接傳回;若無,則當場向資料庫查詢,產生資料物件並存入Cache中,再傳回熱騰騰的資料物件。

由於網站裡要使用這種方式Cache的資料物件不少,我將其中共用的邏輯提取出來變成共用函數--GetCachableData<T>,使用時只要傳入Cache Key、查詢並產生資料物件的函數、保留在Cache中的小時數三個參數,就可以讓資料物件立即具備自動Cache功能。

以下是程式範例:

    /// <summary>
    /// 取得可以被Cache住一段時間的資料
    /// </summary>
    /// <typeparam name="T">資料物件的型別</typeparam>
    /// <param name="key">Cache識別值,需且唯一性</param>
    /// <param name="getDataCallback">重新產生資料物件並傳回的函數</param>
    /// <param name="cacheHours">保留在Cache中的期限(以小時計)</param>
    /// <returns>資料物件</returns>
    public static T GetCachableData<T>(string key, 
                       Func<T> getDataCallback, int cacheHours)
    {
        //檢查是否已在Cache中
        if (HttpContext.Current.Cache[key] == null)
        {
            //呼叫setCallback重新取得資料物件
            T obj = getDataCallback();
            //保存在Cache中
            HttpContext.Current.Cache.Add(
                key, obj, null, 
                DateTime.Now.AddHours(cacheHours), 
                System.Web.Caching.Cache.NoSlidingExpiration,
                System.Web.Caching.CacheItemPriority.High, null);
        }
        //傳回資料物件
        return (T)HttpContext.Current.Cache[key];
    }
 
    //應用範例
    public static void Test()
    {
        List<string> lst =
            GetCachableData<List<string>>("MY_TEST_DATA",
            () =>
            {
                //實務上多透過查詢資料庫或Web Service產生資料物件
                //這裡使用Hard-Coding簡易示範
                List<string> l = new List<string>();
                l.Add("Darkthead");
                l.Add("Jeffrey");
                return l;
            }, 2);
    }

Comments

# by hunterpo

"...變成共用函數--GetChableData<T>..." Cachable 似乎漏了幾個字。

# by Jeffrey

to hunterpo, 感謝指正,已修改過來了。(錯字大王果真名不虛傳吧! 呵呵)

Post a comment