用泛型写Redis缓存与数据库操作工具类

Posted itbac

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用泛型写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);

当调用工具类的方法时,写匿名内部类,去实现从数据库获取数据的逻辑。

 

以上是关于用泛型写Redis缓存与数据库操作工具类的主要内容,如果未能解决你的问题,请参考以下文章

为什么要用泛型呢

java中啥是泛型,怎么用泛型?

C#进阶系列11 泛型

封装php redis缓存操作类

Redis缓存数据库的安装与配置

RedisUtils工具类,设置缓存,然后需要在删除,更新插入的时候清空缓存,保持redis和mysql的数据一致