RedisTemplate-Redis缓存工具类(自己封装的简单工具类)

前言

    这个是基于redis的一个简单的缓存工具类 自己封装的,写的不合理的地方希望大家指出,使用起来也比较简介方便,移植性也比较好,如果换了redis,替换也方便

数据准备:

      1. redis框架

       2.fastjosn框架


1.Cacheable接口
/**
 * 缓存参数接口
 * @param <T>
 */
public interface Cacheable <T>{
    //外部实现数据回传
    public T getData();
}

2.RedisCacheUtil

import com.alibaba.fastjson.JSONObject;
import com.jiuzhm.common.redis.lock.impl.RedisLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.TimeUnit;
/*
1.单个对象使用样例
                String userId = "92839";
		UserInfo user1 = (UserInfo)redisCacheUtil.getCacheData(userId, 1000L, UserInfo.class,new Cacheable() {
			@Override
			public Object getData() {
				return userInfoMapper.queryUserByID("92839",1);
			}
		});
		System.out.println("result="+ user1.getCertName());

2.数组对象使用样例
                String userId = "92839";
		List<UserInfo>list1 = (List)redisCacheUtil.getCacheDataList(userId, 2000L, UserInfo.class,new Cacheable() {
			@Override
			public Object getData() {
				UserInfo user = userInfoMapper.queryUserByID(userId,1);
				List<UserInfo>list = new ArrayList<>(2);
				list.add(user);
				list.add(user);
				list.add(user);
				list.add(user);
				return  list;
			}
		});
		System.out.println("result="+ list1.size());
		for (UserInfo user1 :list1){
			System.out.println("result="+ user1.getCertName());
		}
 */

/**
 * redis缓存帮助类
 *
 * @param <T>
 */
@Service
public class RedisCacheUtil<T> {

    private final static String RedisCacheUtilKeyPre = "RedisCacheUtilKeyPre_";
    private final static String RedisCacheUtilLockKeyPre = "RedisCacheUtilLockKeyPre_";
    @Autowired
    private RedisLock lock;
    @Autowired
    private RedisTemplate redisTemplate;


    /**
     *获取缓存数据对象
     *
     * @param key
     * @param expire  过期时间/秒
     * @param deskClass 对应的类型
     * @param cacheable
     * @return
     */

    public T getCacheData(String key, Long expire, Class deskClass, Cacheable cacheable) {
        return this.getCacheObject(key,expire,deskClass,false,cacheable);
    }

    /**
     * 获取缓存数据对象
     * @param key
     * @param expire    过期时间/秒
     * @param deskClass 对应的类型
     * @param cacheable
     * @return
     */
    public T getCacheDataList(String key, Long expire, Class deskClass, Cacheable cacheable) {
       return this.getCacheObject(key,expire,deskClass,true,cacheable);
    }

    /**
     * 删除缓存
     * @param key
     */
    public void delCacheWith(String key){
        key = this.makeRedisKey(key);
        redisTemplate.delete(key);
    }

    /**
     * 获取缓存数据 如果无缓存 将会从Cacheable中获取 Cacheable需要自己提供数据
     * @param key
     * @param expire   过期时间/秒
     * @param deskClass 对应的类型
     * @param isList  是否List对象
     * @param cacheable
     * @return
     */
    private T getCacheObject(String key, Long expire, Class deskClass,boolean isList, Cacheable cacheable) {
        key = this.makeRedisKey(key);
        String lockKey = RedisCacheUtil.RedisCacheUtilLockKeyPre + key + "_";
        T obj = null;
        //加锁防止缓存击穿
        boolean isLock = this.lock.lock(lockKey);
        try {
            if (isLock) {
                if (isList){
                    obj = this.getCacheList(key, deskClass);
                }else {
                    obj = this.getCacheObject(key, deskClass);
                }
                if (null == obj) {
                    obj = (T) cacheable.getData();
                    if(!(obj instanceof List) && isList){
                        throw new RuntimeException("当前Cacheable接口对应实现的getData返回值必须为List,不能是单个对象");
                    }
                    if(obj instanceof List && !isList){
                        throw new RuntimeException("当前Cacheable接口对应实现的getData返回值必须为单个对象,不能是List");
                    }
                    this.setCacheObject(key, obj, expire);
                }
            }
        } catch (Exception e) {
            System.out.println(e.toString());
        } finally {
            if (isLock) {
                this.lock.unlock(lockKey);
            }
            return obj;
        }
    }


    /**
     * 缓存基本的对象,Integer、String、实体类等
     *
     * @param key   缓存的键值
     * @param value 缓存的值 对象集合等要用fastJosn转成String
     * @return 缓存的对象
     */
    private void setCacheObject(String key, T value, Long expire) {
        key = this.makeRedisKey(key);
        String redisValue = null;
        if (null == value) {
            return;
        }
        if (value instanceof String) {
            redisValue = (String) value;
        } else {
            String objValue = JSONObject.toJSON(value).toString();
            redisValue = (String) objValue;
        }
        ValueOperations<String, String> operation = redisTemplate.opsForValue();
        operation.set(key, redisValue);
        if (null != expire) {
            this.redisTemplate.expire(key, expire, TimeUnit.SECONDS);
        }
    }

    /**
     * 获得缓存的基本对象。
     *
     * @param key 缓存键值
     * @return 缓存键值对应的数据
     */
    private String getCacheObject(String key) {
        key = this.makeRedisKey(key);
        ValueOperations<String, String> operation = redisTemplate.opsForValue();
        return operation.get(key);
    }

    /**
     * 获取缓存对象:对应类型
     *
     * @param key
     * @param deskClass
     * @param <T>
     * @return
     */
    private <T> T getCacheObject(String key, Class deskClass) {
        key = this.makeRedisKey(key);
        String redisValue = this.getCacheObject(key);
        if (null == redisValue) {
            return null;
        }
        T redisObj = (T) JSONObject.parseObject(redisValue, deskClass);
        return redisObj;
    }

    /***
     * 获取缓存数组对象:对应类型
     * @param key
     * @param deskClass
     * @param <T>
     * @return
     */
    private <T> T getCacheList(String key, Class deskClass) {
        key = this.makeRedisKey(key);
        String redisValue = this.getCacheObject(key);
        if (null == redisValue) {
            return null;
        }
        T redisObj = (T) JSONObject.parseArray(redisValue,deskClass);
        return redisObj;
    }

    /**
     * 构造key
     * @param key
     * @return
     */
    private String makeRedisKey(String key){
        if (null==key){
            throw new RuntimeException("key不能为空");
        }
        if (key.contains(RedisCacheUtil.RedisCacheUtilKeyPre)){
            return key;
        }else {
            return RedisCacheUtil.RedisCacheUtilKeyPre+key;
        }
    }
}



使用:以对象数组存储为例

@Resource
RedisCacheUtil redisCacheUtil;

1.首次(看mybatis的执行日志)

        @Test
	public void contextLoads() {
		String userId = "92839";
		List<UserInfo>list1 = (List)redisCacheUtil.getCacheDataList(userId, 2000L, UserInfo.class,new Cacheable() {
			@Override
			public Object getData() {
				UserInfo user = userInfoMapper.queryUserByID(userId,1);
				List<UserInfo>list = new ArrayList<>(4);
				list.add(user);
				list.add(user);
				list.add(user);
				list.add(user);
				return  list;
			}
		});
		System.out.println("result="+ list1.size());
		for (UserInfo user1 :list1){
			System.out.println("result="+ user1.getCertName());
		}
	}

2.非首次且缓存未过期(没有mybatis执行日志也得到数据了)


3.手动删除缓存

this.redisCacheUtil.delCacheWith(userId);

猜你喜欢

转载自blog.csdn.net/aa741649143/article/details/80902282