用泛型寫Redis緩存與數據庫操作工具類


  功能描述: 先從緩存獲取數據,如果緩存沒有,就從數據庫獲取數據,並設置到緩存中,返回數據。

        如果數據庫中沒有數據,需要設置一個緩存標記flagKey,防止暴擊訪問數據庫,用緩存保護數據庫。

        當刪除緩存key時,需要同時刪除flagKey,保證數據庫可被訪問。

  關於java泛型的知識點,這里就跳過了。不理解的就自己去百度一下。

  直接上代碼:

1.先定義泛型接口,用於寫從數據庫獲取數據的方法。

/**
 * 普通數據獲取器
 * 
 */
public interface DataGeter<T> {

    /**
     * 獲取數據接口
     * @return
     */
    public T getData();
}

2.工具類。有一些方法需要自己寫,看注釋。

public class DataUtil {

    /**json轉換工具*/
    private static Gson gson = new Gson();
    
    /**一天的過期秒數*/
    private static final int ONE_DAY_EXPIRE_SECONDS = 1 * 24 * 60 * 60;

    /**
     * 獲取redis中獲取指定data,如果redis中不存在,則從DataGeter接口中獲取,並且寫入redis<br/>
     * 注:該方法會自動創建一個cacheKey + "_flag"的緩存key,作為標記flagKey
     * @param cacheKey-緩存key
     * @param clazz-獲取目標類型
     * @param dataGeter-數據獲取器,原始數據源
     * @param expireSeconds-緩存失效時間
     * @return
     */
    public static <T> T getDataFromRedisOrDataGeter(String cacheKey, Class<T> clazz, DataGeter<T> dataGeter,int expireSeconds) {
        
        T val = RedisClient.getValue(cacheKey, clazz);
        if (val != null) {
            //讓熱數據一直熱下去 <單個key/value>,設置緩存有效期。
            haveChanceToSetKeyExpireTime( cacheKey, expireSeconds) ;
            return val;
        }
        if (RedisClient.existsKey(RedisClient.getFlagKey(cacheKey))) {
            return null;
        }
        
        try {
        //本地鎖 Object lockObject
= LockObjectUtil.getLockObject(cacheKey); synchronized (lockObject) {// 為提升性能 這里不使用分布式鎖 // 標記key,防止集合為空時還不停從數據庫中讀取數據 T data = null; try { data = dataGeter.getData(); } catch (DBException e) { e.printStackTrace(); throw e; } if (data != null) { // 這里最后才設置flag,以免分布式環境下dataGeter.getData();獲取慢,導致后續請求從緩存中取不到數據 //有值不設置flag RedisClient.setValue(cacheKey, data, expireSeconds <= 0 ? RedisDataSource.DEFAULT_EXPIRE_SECONDS : expireSeconds, false); } else { // 不存在數據則往緩存中插入一個flag,過期時間為一天 RedisClient.setValue(RedisClient.getFlagKey(cacheKey), true, ONE_DAY_EXPIRE_SECONDS); } return data; } } finally { //釋放鎖 LockObjectUtil.disposeLock(cacheKey); } } }

當調用工具類的方法時,寫匿名內部類,去實現從數據庫獲取數據的邏輯。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM