RedisTemplate常用操作工具类封装,实现一个函数添加,删除,更新及对应批量操作

使用示例

/**
 * @author evildoer
 * @since 2021-02-05
 */
@Service
@AllArgsConstructor
public class QuestionServiceImpl extends ServiceImpl<QuestionMapper, Question> implements IQuestionService {

    private final RedisTemplate redisTemplate;

    /**
     * @description: 添加一个数据到redis
     * @author: evildoer
     * @datetime: 2021/4/1 12:49
     */
    boolean saveOrUpdateRedis(QuestionVo data){
        // 以hash形式存储
        RedisUtils<String, QuestionVo> redisUtils = new RedisUtils<String, QuestionVo>(RedisConstants.QUESTION_KEY, redisTemplate);
        return redisUtils.saveOrUpdateToRedis(data, QuestionVo::getId);
    }

    /**
     * @description: 添加一个集合数据到redis
     */
    boolean saveOrUpdateRedis(List<QuestionVo> list){
        // 以hash形式存储
        RedisUtils<String, QuestionVo> redisUtils = new RedisUtils<String, QuestionVo>(RedisConstants.QUESTION_KEY, redisTemplate);
        return redisUtils.saveOrUpdateCollectionToRedis(list, QuestionVo::getId);
    }

    /**
     * @description: 从redis获取一条数据
     */
    QuestionVo fetchData(Object key){
        // 以hash形式存储
        RedisUtils<String, QuestionVo> redisUtils = new RedisUtils<String, QuestionVo>(RedisConstants.QUESTION_KEY, redisTemplate);
        return redisUtils.fetchData(key);
    }

    /**
     * @description: 从redis删除一个数据
     */
    QuestionVo deleteData(Object key){
        // 以hash形式存储
        RedisUtils<String, QuestionVo> redisUtils = new RedisUtils<String, QuestionVo>(RedisConstants.QUESTION_KEY, redisTemplate);
        return redisUtils.delete(key);
    }

    /**
     * @description: 从redis删除多个数据
     */
    boolean deleteBatch(Collection<QuestionVo> collection){
        // 以hash形式存储
        RedisUtils<String, QuestionVo> redisUtils = new RedisUtils<String, QuestionVo>(RedisConstants.QUESTION_KEY, redisTemplate);
        return redisUtils.deleteBatch(collection, QuestionVo::getId);
    }
}


工具类


import org.springframework.data.redis.core.RedisTemplate;

import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;

/**
 * @description: 封装redis的常用操作
 * @author: evildoer
 * @datetime: 2021/4/1 12:54
 */
public class RedisUtils<K, V> {

    /**
     * redis最大存储数量
     */
    private Integer size = 1000;

    private final K KEY;

    private final RedisTemplate<K, V> redisTemplate;

    public RedisUtils(K key, RedisTemplate<K, V> redisTemplate) {
        this.KEY = key;
        this.redisTemplate = redisTemplate;
    }

    public RedisUtils(K key, RedisTemplate<K, V> redisTemplate, Integer size) {
        this.KEY = key;
        this.size = size;
        this.redisTemplate = redisTemplate;
    }

    /**
     * @description: 以hash的形式添加一条数据到redis
     * @return: boolean
     * @author: evildoer
     * @datetime: 2021/4/1 12:58
     */
    public boolean saveOrUpdateToRedis(V data, Function<V, ?> function) {
        // 从缓存取数据列表
        Map<Object, Object> map = redisTemplate.opsForHash().entries(KEY);
        // 超出redis最大存储数量, 直接清空
        if (map.size() > size) {
            map.clear();
        }
        map.put(function.apply(data), data);
        // 更新redis
        redisTemplate.opsForHash().putAll(KEY, map);
        return true;
    }

    /**
     * @description: 以hash的形式添加一个集合的数据到redis
     * @return: boolean
     * @author: evildoer
     * @datetime: 2021/4/1 12:58
     */
    public boolean saveOrUpdateCollectionToRedis(Collection<V> collection, Function<V, ?> function) {
        // 从缓存取数据列表
        Map<Object, Object> map = redisTemplate.opsForHash().entries(KEY);
        // 更新redis, 不考虑size
        redisTemplate.opsForHash().putAll(KEY, map);
        collection.forEach(data -> {
            map.put(function.apply(data), data);
        });
        // 更新redis
        redisTemplate.opsForHash().putAll(KEY, map);
        return true;
    }


    /**
     * @description: 通过Map的key从redis获取一条数据
     * @author: evildoer
     * @datetime: 2021/4/1 12:58
     */
    public V fetchData(Object key) {
        // 从缓存取数据
        Map<Object, Object> map = redisTemplate.opsForHash().entries(KEY);
        Object data = map.get(key);
        if (null != data) {
            return (V) data;
        }
        return null;
    }

    /**
     * @description: 通过key从Map形式储存的redis删除一条数据, 返回删除的数据
     * @author: evildoer
     * @datetime: 2021/4/1 12:58
     */
    public V delete(Object key) {
        // 从缓存删除数据
        Map<Object, Object> map = redisTemplate.opsForHash().entries(KEY);
        Object data = map.get(key);
        if (null != data) {
            Object object = map.remove(key);
            // 更新redis
            redisTemplate.opsForHash().putAll(KEY, map);
            return (V) object;
        }
        return null;
    }

    /**
     * @description: 通过key从Map形式储存的redis删除多条数据
     * @author: evildoer
     * @datetime: 2021/4/1 12:58
     */
    public boolean deleteBatch(Collection<V> collection, Function<V, ?> function) {
        AtomicBoolean result = new AtomicBoolean(false);
        // 从缓存删除数据
        Map<Object, Object> map = redisTemplate.opsForHash().entries(KEY);
        collection.forEach(data -> {
            Object key = function.apply(data);
            Object obj = map.get(key);
            if (null != obj) {
                result.set(true);
                map.remove(key);
            }
        });
        // 更新redis
        if (result.get()) {
            redisTemplate.opsForHash().putAll(KEY, map);
        }
        return result.get();
    }

    /**
     * @description: 以List的形式添加一个数据到redis
     * @author: evildoer
     * @datetime: 2021/4/1 12:49
     */
    public <D> boolean saveOrUpdateDataToRedis(D data, Function<D, ?> function) {
        // 从缓存取数据列表
        V v = redisTemplate.opsForList().leftPop(KEY);
        List<D> list = null;
        if (null == v) {
            list = new LinkedList<>();
        } else {
            list = (List<D>) v;
        }
        // 是否要加入redis
        boolean flag = true;
        for (int i = 0; i < list.size(); i++) {
            // 判断key是否相等
            if (function.apply(data).equals(function.apply(list.get(i)))) {
                // 查找到了, 修改flag为false, 更新redis
                flag = false;
                list.set(i, data);
            }
        }
        if(flag){
            // 加入redis
            list.add(data);
        }
        // 检查redis数据量, 超出预设值直接清理一半数据
        if (list.size() >= size) {
            list.subList(size / 2, list.size());
            this.clear();
        }
        // 更新redis
        redisTemplate.opsForList().leftPush(KEY, (V) list);
        return true;
    }


    /**
     * @description: 以List的形式添加一个集合的数据到redis
     * @author: evildoer
     * @datetime: 2021/4/1 12:49
     */
    public <D> boolean saveOrUpdateDataCollectionToRedis(Collection<D> collection, Function<D, ?> function) {
        // 从缓存取数据列表
        V v = redisTemplate.opsForList().leftPop(KEY);
        List<D> list = null;
        if (null == v) {
            list = new LinkedList<>();
        } else {
            list = (List<D>) v;
        }
        for (int i = 0; i < list.size(); i++) {
            D data = findCollection(function.apply(list.get(i)), collection, function);
            if (null == data) {
                // 加入redis
                list.add(list.get(i));
            } else {
                // 更新redis
                list.set(i, data);
            }
        }

        // 更新redis
        redisTemplate.opsForList().leftPush(KEY, (V) list);
        return true;
    }

    /**
     * @param key 标识
     * @description: 通过list的形式从redis获取一条数据
     * @author: evildoer
     * @datetime: 2021/4/1 12:58
     */
    public <D> D fetchData(Object key, Function<D, ?> function) {
        // 从缓存取数据列表
        V v = redisTemplate.opsForList().leftPop(KEY);
        return this.findCollection(key, (List<D>) v, function);
    }

    /**
     * @description: 通过key从List形式储存的redis删除一条数据, 返回删除的数据
     * @author: evildoer
     * @datetime: 2021/4/1 12:58
     */
    public <D> D delete(Object key, Function<D, ?> function) {
        // 从缓存取数据列表
        V v = redisTemplate.opsForList().leftPop(KEY);
        List<D> list = (List<D>) v;
        if (null == v) {
            return null;
        } else {
            list = (List<D>) v;
        }
        D result = null;
        for (int i = 0; i < list.size(); i++) {
            if (function.apply(list.get(i)).equals(key)) {
                result = list.remove(i);
            }
        }
        // 更新redis
        if (null != result) {
            redisTemplate.opsForList().leftPush(KEY, (V) list);
        }
        return result;
    }

    /**
     * @description: 通过key从List形式储存的redis删除多条数据
     * @author: evildoer
     * @datetime: 2021/4/1 12:58
     */
    public <D> boolean deleteList(Collection<D> collection, Function<D, ?> function) {
        // 从缓存取数据列表
        V v = redisTemplate.opsForList().leftPop(KEY);
        List<D> list = (List<D>) v;
        if (null == v) {
            return false;
        } else {
            list = (List<D>) v;
        }
        boolean result = false;
        for (int i = 0; i < list.size(); i++) {
            if (null != findCollection(function.apply(list.get(i)), collection, function)) {
                result = true;
                list.remove(i);
            }
        }
        // 更新redis
        if (result) {
            redisTemplate.opsForList().leftPush(KEY, (V) list);
        }
        return result;
    }

    /**
     * 查看集合内是否有该数据(空返回null)
     */
    private <D> D findCollection(Object key, Collection<D> collection, Function<D, ?> function) {
        if (null == key || null == collection || collection.isEmpty()) {
            return null;
        }
        AtomicReference<D> result = new AtomicReference<>(null);
        collection.forEach(data -> {
            if (key.equals(function.apply(data))) {
                result.set(data);
            }
        });
        return result.get();
    }

    /**
     * 清空Redis存储的对应KEY的数据
     */
    public boolean clear() {
        redisTemplate.delete(KEY);
        return true;
    }

    public Integer getSize() {
        return size;
    }

    public void setSize(Integer size) {
        this.size = size;
    }
}


上一篇:redisTemplate、jedis、lettuce、redission的对比


下一篇:springboot2.3.2.RELEASE集成redis,动态切换数据库