redisTemplate自定义序列化配置,更改其默认序列化器。以及序列化反序列化注意问题

本文介绍了Redis中使用自定义序列化配置解决默认序列化导致的乱码问题,提供了RedisTemplate的配置代码示例,并详细讲解了RedisUtil工具类,包括通用操作、String类型、List类型和Set类型的操作方法,便于在实际开发中进行数据的存取和管理。
摘要由CSDN通过智能技术生成

 问题场景:
如果我们使用redis默认的序列化器,会发现redis可视化工具中展示的是乱码,非常不友好

 为什么要序列化?
1、如果存储字符串类型的,不需要序列化。但如果存储Bean对象或者集合类型的数据,就必须要序列化
2、对于Bean之类的只需要让它实现Serializable接口就行,反序列化也不需要强转

解决:
配置redisTemplate的序列化器,使用自定义的序列化器,不使用redis默认的,代码如下:

package com.hkl.mpjoin.configure;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import javax.annotation.Resource;

/**
 * <p>ClassName: RedisConfigure</p >
 * <p>Description: redisTemplate自定义序列化配置,更改其默认序列化器</p >
 * <p>Author: hkl</p >
 * <p>Date: 2021/10/23</p >
 */
@Configuration
public class RedisConfigure extends CachingConfigurerSupport {
    @Resource
    private RedisConnectionFactory factory;


    @Bean(name = "redisTemplate")
    public <K, V> RedisTemplate<K, V> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.activateDefaultTyping(
                LaissezFaireSubTypeValidator.instance,
                ObjectMapper.DefaultTyping.NON_FINAL,
                JsonTypeInfo.As.WRAPPER_ARRAY);
        //jackson序列化默认存在不认识字段报错,用户可以自己设置将其忽略
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);


        //================================= RedisTemplate 序列化设置 start ==============================
        RedisTemplate<K, V> template = new RedisTemplate<K, V>();
        template.setConnectionFactory(redisConnectionFactory);

        //key、hashKey采用String的序列化方式
        //template.setKeySerializer(new GenericToStringSerializer(Object.class));
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());

        //value、HashValue采用Jackson的序列化方式
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));
        template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));

        //初始化函数,使用以上设置的序列化参数
        template.afterPropertiesSet();
        //设置Redis事务一致支持,可配合@Transactional使用(需要手工关闭连接的谨慎使用)
        template.setEnableTransactionSupport(true);
        //================================= RedisTemplate 序列化设置 end ================================
        return template;
    }

    @Bean(name = "stringRedisTemplate")
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
        StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
        stringRedisTemplate.setConnectionFactory(redisConnectionFactory);

        //key、value采用String的序列化方式
        stringRedisTemplate.setKeySerializer(new StringRedisSerializer());
        stringRedisTemplate.setValueSerializer(new StringRedisSerializer());
        stringRedisTemplate.setStringSerializer(new StringRedisSerializer());

        //初始化函数,使用以上设置的序列化参数
        stringRedisTemplate.afterPropertiesSet();
        //设置Redis事务一致支持,可配合@Transactional使用(需要手工关闭连接的谨慎使用)
        stringRedisTemplate.setEnableTransactionSupport(true);
        return stringRedisTemplate;
    }






    @Bean(name = "redisTemplateTemp")
    public RedisTemplate<String, Object> redisTemplateTemp(RedisConnectionFactory redisConnectionFactory) {
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();

        //使用 <String, Object> 泛型,避免类型转换
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        //key、hashKey采用String的序列化方式
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);

        //value、HashValue采用Jackson的序列化方式
        redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
        redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);

        //redisTemplate.setEnableDefaultSerializer(true);
        //redisTemplate.setDefaultSerializer(new StringRedisSerializer());
        //redisTemplate.setStringSerializer(new StringRedisSerializer());

        //初始化函数,使用以上设置的序列化参数
        redisTemplate.afterPropertiesSet();
        //设置Redis事务一致支持,可配合@Transactional使用(需要手工关闭连接的谨慎使用)
        redisTemplate.setEnableTransactionSupport(true);
        return redisTemplate;
    }


}

以上配置好之后,redis可视化端就会正常显示json格式的数据

使用:
注入 redisTemplate 对象即可获取key对应的value

@Resource
RedisTemplate<String, Object> redisTemplate;

注意
1、最好使用 @Resource 注入,注入的 RedisTemplate 类型、泛型和写入时的 RedisTemplate 类型保持一致,否则可能会出现获取不到value的问题
2、redis 反序列化时所用的dto属性必须全包含序列化时的dto全属性,反序列化所用的dto可以增加属性,但不能删除修改属性,否则会报错找不到对应属性
3、推荐做法:缓存存储时直接存储json字符串,使用时直接把json串反序列化就行了。不推荐redis直接序列化是因为对dto所在的服务、包都有要求,在其他服务中即使同名同属性也无法反序列化,除非使用的还是原来包下的dto才可以,不够灵活

RedisUtil工具类、各个数据类型常用方法及介绍:

package com.hkl.mpjoin.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.core.Cursor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ScanOptions;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * <p>Description:Redis工具类</p>
 * <p>Description:存储对象实例类型的数据,需要有无参构造方法,否则报错</p>
 *
 * <p>Author:hkl</p>
 * <p>Date:2022/9/15</p>
 */
@Slf4j
@Component
public class RedisUtil {

    @Resource(name = "redisTemplate")
    private RedisTemplate<String, Object> redisTemplate;

    @Resource(name = "stringRedisTemplate")
    private StringRedisTemplate stringRedisTemplate;





    //################################################## 通用操作 start #################################################
    /**
     * <p>删除单个key值</p>
     *
     * @author hkl
     * @date 2022/9/15
     */
    public boolean delete(String key) {
        try {
            redisTemplate.delete(key);
            return true;
        } catch (Exception e) {
            log.error("RedisUtil method delete Exception:", e);
        }
        return false;
    }

    /**
     * <p>批量删除key值</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public boolean delete(List<String> keys) {
        try {
            redisTemplate.delete(keys);
            return true;
        } catch (Exception e) {
            log.error("RedisUtil method delete Exception:", e);
        }
        return false;
    }

    /**
     * <p>把key设置过期时间,默认秒</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public boolean expire(String key, long time, TimeUnit timeUnit) {
        try {
            if (ObjectUtil.isNull(timeUnit)) {
                timeUnit = TimeUnit.SECONDS;
            }
            //设置过期时间
            redisTemplate.expire(key, time, timeUnit);
            return true;
        } catch (Exception e) {
            log.error("RedisUtil method expire Exception:", e);
        }
        return false;
    }

    /**
     * <p>设置到指定日期过期</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Boolean expireAt(String key, Date date) {
        return redisTemplate.expireAt(key, date);
    }

    /**
     * <p>获取匹配的key集合,返回一个Set集合</p>
     * <p>例如:获取所有的key【redisTemplate.keys("*")】,获取带前缀的key【redisTemplate.keys(prefix.concat("*"))】</p>
     *
     * @param pattern 表达式(*、pro_*等),支持模糊匹配
     * @author hkl
     * @date 2022/11/12
     */
    public Set<String> getPatternKey(String pattern) {
        return redisTemplate.keys(pattern);
    }

    /**
     * <p>对key重命名</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public boolean renameKey(String oldKey, String newKey) {
        try {
            redisTemplate.rename(oldKey, newKey);
            return true;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * <p>返回key对应值的类型</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public DataType getKeyType(String key) {
        return redisTemplate.type(key);
    }

    /**
     * <p>如果旧key存在,将旧key改为新key</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Boolean renameOldKeyIfAbsent(String oldKey, String newKey) {
        try {
            if(redisTemplate.hasKey(oldKey)){
                return redisTemplate.renameIfAbsent(oldKey, newKey);
            }
        } catch (Exception e) {
            log.error("renameOldKeyIfAbsent出现异常:{}", e.getMessage());
            throw new RuntimeException(e);
        }
        return false;
    }

    /**
     * <p>从keys中随机获取一个key</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public String getRandomKey() {
        return redisTemplate.randomKey();
    }

    /**
     * <p>返回key所对应的剩余过期时间</p>
     * <p>-1为没有过期时间</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Long getExpire(String key) {
        return redisTemplate.getExpire(key);
    }

    /**
     * <p>返回key所对应的剩余过期时间,并指定时间单位</p>
     * <p>-1为没有过期时间</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Long getExpire(String key, TimeUnit unit) {
        return redisTemplate.getExpire(key, unit);
    }

    /**
     * <p>将有过期时间的key持久化保存,改为-1</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Boolean persistKey(String key) {
        return redisTemplate.persist(key);
    }

    /**
     * <p>将当前数据库的key移动到指定的redis数据库中</p>
     * <p>同一个数据库下不可移动,会报错</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Boolean moveToDbIndex(String key, int dbIndex) {
        return redisTemplate.move(key, dbIndex);
    }

    /**
     * <p>判断 key 是否存在</p>
     *
     * @author hkl
     * @date 2022/9/15
     */
    public Boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            log.error("RedisUtil method hasKey Exception:", e);
        }
        return false;
    }
    //################################################## 通用操作 end #################################################






    //################################################## String类型 start #################################################

    /**
     * <p>根据key获取value字符串</p>
     *
     * @author hkl
     * @date 2022/9/15
     */
    public String getStr(String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }

    /**
     * <p>返回key中字符串的截取字符,包含start、end索引</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public String getStr(String key, long start, long end) {
        return stringRedisTemplate.opsForValue().get(key, start, end);
    }

    /**
     * <p>获取多个key对应的值</p>
     *
     * @return
     * @author hkl
     * @date 2022/11/12
     */
    public List<String> multiGetStr(List<String> keys) {
        return stringRedisTemplate.opsForValue().multiGet(keys);
    }

    /**
     * <p>获取key对应的值长度</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Long sizeStr(String key) {
        return stringRedisTemplate.opsForValue().size(key);
    }

    /**
     * <p>把字符串写入缓存(key有就覆盖没有就添加),key为键、value为值</p>
     *
     * @author hkl
     * @date 2022/9/15
     */
    public boolean setStr(String key, String value) {
        try {
            stringRedisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            log.error("RedisUtil method set Exception:", e);
        }
        return false;
    }

    /**
     * <p>把字符串写入缓存(key有就覆盖没有就添加),具有时效性(默认为秒)</p>
     *
     * @author hkl
     * @date 2022/9/15
     */
    public boolean setStr(String key, String value, long time, TimeUnit timeUnit) {
        try {
            if (ObjectUtil.isNull(timeUnit)) {
                timeUnit = TimeUnit.SECONDS;
            }
            stringRedisTemplate.opsForValue().set(key, value, time, timeUnit);
            return true;
        } catch (Exception e) {
            log.error("RedisUtil method set Exception:", e);
        }
        return false;
    }

    /**
     * <p>当key不存在则添加成功返回true,否则不做动作返回false</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Boolean setIfAbsentStr(String key, String value) {
        return stringRedisTemplate.opsForValue().setIfAbsent(key, value);
    }

    /**
     * <p>写入多个key、value到缓存,字符串类型</p>
     * <p>key存在则更新,不存在则添加</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public void multiSetStr(Map<String, String> map) {
        stringRedisTemplate.opsForValue().multiSet(map);
    }

    /**
     * <p>写入多个key、value到缓存,字符串类型</p>
     * <p>当全部key都不存在则添加成功返回true,否则不做动作返回false</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Boolean multiSetIfAbsentStr(Map<String, String> map) {
        return stringRedisTemplate.opsForValue().multiSetIfAbsent(map);
    }

    /**
     * <p>当key存在获取key当前的值,然后把值更新为value,否则添加key、value</p>
     *
     * @param
     * @author hkl
     * @date 2022/9/15
     */
    public String getAndSetStr(String key, String value) {
        try {
            return stringRedisTemplate.opsForValue().getAndSet(key, value);
        } catch (Exception e) {
            log.error("RedisUtil method getAndSet Exception:", e);
        }
        return "";
    }

    /**
     * <p>当key存在,在key对应的原有值的基础上追加value到末尾,否则添加key、value</p>
     * <p>返回追加后的值长度</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public boolean appendStr(String key, String value) {
        try {
            Integer append = stringRedisTemplate.opsForValue().append(key, value);
            return (ObjectUtil.isNotNull(append) && append > 0);
        } catch (Exception e) {
            log.error("RedisUtil method append Exception:", e);
        }
        return false;
    }

    /**
     * <p>以增量方式获取key对应的数值,key不存在则添加,默认值是1,默认增量因子是1</p>
     *
     * @author hkl
     * @date 2022/11/15
     */
    public Long increment(String key) {
        return stringRedisTemplate.opsForValue().increment(key);
    }

    /**
     * <p>以增量方式获取key对应的数值,increment是增量因子,返回增量之后的结果</p>
     * <p>key存在则递增,不存在则添加key、increment</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Long increment(String key, long increment) {
        return stringRedisTemplate.opsForValue().increment(key, increment);
    }

    /**
     * <p>以增量方式获取key对应的数值,increment是增量因子,返回增量之后的结果</p>
     * <p>key存在则递增,不存在则添加key、increment</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Double increment(String key, double increment) {
        return stringRedisTemplate.opsForValue().increment(key, increment);
    }

    /**
     * <p>以减量方式获取key对应的数值,key不存在则添加,默认值是-1,默认减量因子是1</p>
     *
     * @author hkl
     * @date 2022/11/15
     */
    public Long decrement(String key) {
        return stringRedisTemplate.opsForValue().decrement(key);
    }

    /**
     * <p>以减量方式获取key对应的数值,key不存在则添加,减量因子是decrement</p>
     *
     * @author hkl
     * @date 2022/11/15
     */
    public Long decrement(String key, long decrement) {
        return stringRedisTemplate.opsForValue().decrement(key, decrement);
    }

    /**
     * <p>对key所储存的字符串值,获取指定偏移量上的位(bit)</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Boolean getBit(String key, Long offset) {
        return stringRedisTemplate.opsForValue().getBit(key, offset);
    }


    /**
     * <p>加锁</p>
     *
     * @author hkl
     * @date 2022/9/15
     */
    public boolean lock(String key, String value, long time) {
        try {
            Boolean setIfAbsentRes = stringRedisTemplate.opsForValue().setIfAbsent(key, value);
            if (setIfAbsentRes) {
                //设置成功,加锁设置过期时间
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
                return true;
            }
        } catch (Exception e) {
            log.error("RedisUtil method setIfAbsent Exception:", e);
        }
        return false;
    }

    /**
     * <p>释放锁</p>
     *
     * @author hkl
     * @date 2022/9/15
     */
    public boolean unlock(String key, String value) {
        try {
            String res = stringRedisTemplate.opsForValue().get(key);
            if (value.equals(res)) {
                redisTemplate.delete(key);
                return true;
            }
        } catch (Exception e) {
            log.error("RedisUtil method unlock Exception:", e);
        }
        return false;
    }
    //################################################## String类型 end #################################################






    //################################################## List类型 start #################################################

    /**
     * <p>在key列表最左索引处(最前面),添加一个元素</p>
     * <p>key不存在则添加key,增量添加元素(List是可重复列表)</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Long leftPushList(String key, Object value) {
        return redisTemplate.opsForList().leftPush(key, value);
    }

    /**
     * <p>在key列表最左索引处(最前面),添加多个元素</p>
     * <p>key不存在则添加key,增量添加元素(List是可重复列表)</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Long leftPushAllList(String key, List<Object> values) {
        return redisTemplate.opsForList().leftPushAll(key, values);
    }

    /**
     * <p>在key列表中的 pivot 元素前面添加value元素</p>
     * <p>pivot元素不存在则不添加</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Long leftPushList(String key, Object pivot, Object value) {
        return redisTemplate.opsForList().leftPush(key, pivot, value);
    }

    /**
     * <p>key列表存在的时候,在列表最左边添加一个元素,否则不做动作</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Long leftPushIfPresentList(String key, Object value) {
        return redisTemplate.opsForList().leftPushIfPresent(key, value);
    }

    /**
     * <p>按照先进先出的顺序添加,单个元素</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Long rightPushList(String key, Object value) {
        return redisTemplate.opsForList().rightPush(key, value);
    }

    /**
     * <p>按照先进先出的顺序添加,多个元素</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Long rightPushAllList(String key, List<Object> values) {
        return redisTemplate.opsForList().rightPushAll(key, values);
    }

    /**
     * <p>按照先进先出的顺序在pivot元素右边添加,单个元素</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Long rightPushList(String key, Object pivot, Object value) {
        return redisTemplate.opsForList().rightPush(key, pivot, value);
    }

    /**
     * <p>key列表存在的时候,在列表最左边添加一个元素,否则不做动作</p>
     *
     * @author hkl
     * @date 2022/11/16
     */
    public Long rightPushIfPresentList(String key, String value){
        return redisTemplate.opsForList().rightPushIfPresent(key, value);
    }

    /**
     * <p>添加指定索引的元素</p>
     * <p>覆盖指定索引已有元素。指定索引不可越界,会报错</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public void setList(String key, long index, Object value) {
        redisTemplate.opsForList().set(key, index, value);
    }

    /**
     * <p>根据索引获取key对应列表中的元素</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Object indexList(String key, long index) {
        return redisTemplate.opsForList().index(key, index);
    }

    /**
     * <p>最好不要范围越界</p>
     * <p>获取key列表指定索引范围内的元素(start开始位置、必须大于等于0,end结束位置、可以为负数-1)</p>
     * <p>包括startIndex、endIndex元素,startIndex小于0返回空,endIndex为-1返回所有元素</p>
     * <p>(0, -1)返回所有元素</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public List<Object> rangeList(String key, long startIndex, long endIndex) {
        return redisTemplate.opsForList().range(key, startIndex, endIndex);
    }

    /**
     * <p>获取并移除key对应列表中最左边第一个元素</p>
     * <p>如果列表中没有元素会阻塞列表,直到等待超时或有元素为止</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Object leftPopList(String key, long timeout, TimeUnit timeUnit) {
        if (ObjectUtil.isNull(timeUnit)) {
            timeUnit = TimeUnit.SECONDS;
        }
        return redisTemplate.opsForList().leftPop(key, timeout, timeUnit);
    }

    /**
     * <p>获取并移除key对应列表中最右边第一个元素</p>
     * <p>如果列表中没有元素会阻塞列表,直到等待超时或有元素为止</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Object rightPopList(String key, long timeout, TimeUnit timeUnit) {
        if (ObjectUtil.isNull(timeUnit)) {
            timeUnit = TimeUnit.SECONDS;
        }
        return redisTemplate.opsForList().rightPop(key, timeout, timeUnit);
    }

    /**
     * <p>从sourceKey列表中取出最后一个元素,把这个元素添加到destinationKey(不存在则新添加)列表中的最左边第一个</p>
     * <p>如果列表中没有元素会阻塞列表,直到等待超时或有元素为止</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Object rightPopAndLeftPushList(String sourceKey, String destinationKey, long timeout, TimeUnit timeUnit) {
        if (ObjectUtil.isNull(timeUnit)) {
            timeUnit = TimeUnit.SECONDS;
        }
        return redisTemplate.opsForList().rightPopAndLeftPush(sourceKey, destinationKey, timeout, timeUnit);
    }

    /**
     * <p>移除key列表中值等于value的元素,这里的index是数量,不是索引</p>
     * <p>index=0,删除所有值等于value的元素; index>0,从最左边开始删除第index个值等于value的元素; index<0, 从最右边开始删除第index个值等于value的元素</p>
     * <p>返回被删除元素的数量</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Long removeList(String key, long index, Object value) {
        return redisTemplate.opsForList().remove(key, index, value);
    }

    /**
     * <p>获取key列表的长度</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Long sizeList(String key) {
        return redisTemplate.opsForList().size(key);
    }

    /**
     * <p>将列表进行裁剪,移除掉start到end之间的元素(包括start不包括end)</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public void trimList(String key, long start, long end) {
        redisTemplate.opsForList().trim(key, start, end);
    }
    //################################################## List类型 end #################################################






    //################################################## Set类型 start #################################################

    /**
     * <p>向key对应的值set集合中添加元素</p>
     * <p>如果添加的元素与集合中的元素重复则不添加,不重复的元素则添加</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public boolean addSet(String key, Object... values) {
        boolean result = false;
        try {
            Long add = redisTemplate.opsForSet().add(key, values);
            result = true;
        } catch (Exception e) {
            log.error("RedisUtil method add Exception:", e);
        }
        return result;
    }

    /**
     * <p>向key对应的值set集合中添加元素</p>
     * <p>如果添加的元素与集合中的元素重复则不添加,不重复的元素则添加</p>
     *
     * @author hkl
     * @date 2022/11/13
     */
    public boolean addSetByList(String key, List<Object> objects) {
        try {
            if (CollUtil.isEmpty(objects)) {
                log.info("objects is null!");
                return false;
            }
            redisTemplate.opsForSet().add(key, ArrayUtil.toArray(objects, Object.class));
            return true;
        } catch (Exception e) {
            log.error("RedisUtil method add Exception:", e);
        }
        return false;
    }

    /**
     * <p>移除key对应的值set集合中一个或多个元素</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public boolean removeSet(String key, Object... values) {
        boolean result = false;
        try {
            Long removeRes = redisTemplate.opsForSet().remove(key, values);
            if (ObjectUtil.isNotNull(removeRes) && removeRes > 0) {
                result = true;
            }
        } catch (Exception e) {
            log.error("RedisUtil method remove Exception:", e);
        }
        return result;
    }

    /**
     * <p>删除并且返回一个随机的元素</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Object popSet(String key) {
        return redisTemplate.opsForSet().pop(key);
    }

    /**
     * <p>获取Set集合的大小</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Long sizeSet(String key) {
        return redisTemplate.opsForSet().size(key);
    }

    /**
     * <p>校验key对应的Set集合是否存在该value</p>
     *
     * @author hkl
     * @date 2022/9/16
     */
    public Boolean isMemberSet(String key, Object value) {
        return redisTemplate.opsForSet().isMember(key, value);
    }

    /**
     * <p>获取集合的所有元素</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Set<Object> membersSet(String key) {
        return redisTemplate.opsForSet().members(key);
    }

    /**
     * <p>随机获取集合中的一个元素</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Object randomMemberSet(String key) {
        return redisTemplate.opsForSet().randomMember(key);
    }

//    /**
//     * <p>获取两个集合的交集(key对应的Set集合和otherKey对应的Set集合,二者集合的交集)</p>
//     *
//     * @author hkl
//     * @date 2022/11/12
//     */
//    public Set<Object> intersect(String key, String otherKey){
//        return redisTemplate.opsForSet().intersect(key, otherKey);
//    }

    /**
     * <p>获取key对应的集合与otherKeyList对应的集合的交集</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Set<Object> intersectSet(String key, List<String> otherKeyList) {
        return redisTemplate.opsForSet().intersect(key, otherKeyList);
    }

//    /**
//     * <p>key集合与otherKey集合的交集存储到destKey对应的集合中</p>
//     *
//     * @author hkl
//     * @date 2022/11/12
//     */
//    public Long intersectAndStore(String key, String otherKey, String destKey) {
//        return redisTemplate.opsForSet().intersectAndStore(key, otherKey, destKey);
//    }

    /**
     * <p>key对应的集合与otherKeyList对应的集合的交集存储到destKey对应的集合中</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Long intersectAndStoreSet(String key, List<String> otherKeyList, String destKey) {
        return redisTemplate.opsForSet().intersectAndStore(key, otherKeyList, destKey);
    }

    /**
     * <p>获取key对应的集合与otherKeyList对应的集合的并集</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Set<Object> unionSet(String key, List<String> otherKeyList) {
        return redisTemplate.opsForSet().union(key, otherKeyList);
    }

    /**
     * <p>key对应集合与otherKeyList对应集合的并集存储到destKey对应的集合中</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Long unionAndStoreSet(String key, List<String> otherKeyList, String destKey) {
        return redisTemplate.opsForSet().unionAndStore(key, otherKeyList, destKey);
    }

    /**
     * <p>获取两个或多个集合的差集</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Set<Object> differenceSet(String key, List<String> otherKeyList) {
        return redisTemplate.opsForSet().difference(key, otherKeyList);
    }

    /**
     * <p>两个或多个集合的差集存储到destKey对应的集合中</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Long differenceAndStoreSet(String key, List<String> otherKeyList, String destKey) {
        return redisTemplate.opsForSet().differenceAndStore(key, otherKeyList, destKey);
    }

    /**
     * <p>遍历set类似于Interator(ScanOptions.NONE为显示所有的)</p>
     *
     * @author hkl
     * @date 2022/11/12
     */
    public Cursor<Object> scanSet(String key, ScanOptions options) {
        return redisTemplate.opsForSet().scan(key, options);
    }
    //################################################## Set类型 end #################################################






    //################################################## Hash类型 start #################################################
    /**
     * <p>获取key对应的Map中小key对应的值,没有则返回null</p>
     *
     * @author hkl
     * @date 2022/11/13
     */
    public Object getHash(String key, Object hashKey){
        return redisTemplate.opsForHash().get(key, hashKey);
    }

    /**
     * <p>获取key对应的完整Map集合</p>
     *
     * @author hkl
     * @date 2022/11/13
     * @param
     * @return
     */
    public Map<Object, Object> entriesHash(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * <p>在key对应的Map中添加键hashKey和值value</p>
     * <p>hashKey存在则更新,不存在则添加</p>
     *
     * @author hkl
     * @date 2022/11/13
     */
    public void putHash(String key, Object hashKey, Object value) {
        redisTemplate.opsForHash().put(key, hashKey, value);
    }

    /**
     * <p>在key下,以Map集合的形式添加键值</p>
     * <p>Map中的小hashKey存在则更新,不存在则添加</p>
     *
     * @author hkl
     * @date 2022/11/13
     */
    public void putAllHash(String key, Map<String, Object> maps) {
        redisTemplate.opsForHash().putAll(key, maps);
    }

    /**
     * <p>在key对应的Map中,当hashKey不存在则添加键值返回true,存在则不做动作返回false</p>
     *
     * @author hkl
     * @date 2022/11/13
     */
    public Boolean putIfAbsentHash(String key, Object hashKey, Object value) {
        return redisTemplate.opsForHash().putIfAbsent(key, hashKey, value);
    }

    /**
     * <p>在key对应的Map中,删除一个或者多个小hashKey,小hashKey不存在也不会报错</p>
     *
     * @author hkl
     * @date 2022/11/13
     */
    public Long deleteHash(String key, Object... hashKeys) {
        return redisTemplate.opsForHash().delete(key, hashKeys);
    }

    /**
     * <p>查看key对应的Map中,是否存在小hashKey</p>
     *
     * @author hkl
     * @date 2022/11/13
     */
    public Boolean hasKeyHash(String key, Object hashKey) {
        return redisTemplate.opsForHash().hasKey(key, hashKey);
    }

    /**
     * <p>增量方式获取key对应的Map集合中hashKey键的整数值,增量因子是increment</p>
     *
     * @author hkl
     * @date 2022/11/13
     */
    public Long incrementHash(String key, Object hashKey, long increment) {
        return redisTemplate.opsForHash().increment(key, hashKey, increment);
    }

    /**
     * <p>获取key对应的Map集合中所有键字段</p>
     *
     * @author hkl
     * @date 2022/11/13
     */
    public Set<Object> keysHash(String key) {
        return redisTemplate.opsForHash().keys(key);
    }

    /**
     * <p>获取key对应的Map集合中键数量</p>
     *
     * @author hkl
     * @date 2022/11/13
     */
    public Long sizeHash(String key) {
        return redisTemplate.opsForHash().size(key);
    }

    /**
     * <p>获取key对应的Map集合中所有的值</p>
     *
     * @author hkl
     * @date 2022/11/13
     */
    public List<Object> valuesHash(String key) {
        return redisTemplate.opsForHash().values(key);
    }

    /**
     * <p>在key对应的Map集合中,获取多个小hashKey的值</p>
     *
     * @author hkl
     * @date 2022/11/14
     */
    public List<Object> multiGetHash(String key, List<Object> hashKeys) {
        return redisTemplate.opsForHash().multiGet(key, hashKeys);
    }

    /**
     * <p>获取key对应的Map集合中小hashKey对应值的长度</p>
     * <p>因为多了存储值多了引号,所以长度比预期多2个单位</p>
     *
     * @author hkl
     * @date 2022/11/14
     */
    public Long lengthOfValueHash(String key, String hashKey) {
         return redisTemplate.opsForHash().lengthOfValue(key, hashKey);
    }

    /**
     * <p>匹配获取键值对,ScanOptions.NONE为获取全部键对</p>
     * <p>ScanOptions.scanOptions().match("map1").build() 匹配获取键位map1的键值对,不能模糊匹配</p>
     * <p>用法示例:
     *     Cursor<Map.Entry<Object,Object>> cursor = redisTemplate.opsForHash().scan("hashValue",ScanOptions.scanOptions().match("map1").build());
     *      while (cursor.hasNext()){
     *         Map.Entry<Object,Object> entry = cursor.next();
     *         System.out.println("通过scan(H key, ScanOptions options)方法获取匹配键值对:" + entry.getKey() + "---->" + entry.getValue());
     *     }
     * </p>
     *
     * @author hkl
     * @date 2022/11/13
     */
    public Cursor<Map.Entry<Object, Object>> scanHash(String key, ScanOptions options) {
        return redisTemplate.opsForHash().scan(key, options);
    }

    //################################################## Hash类型 end ##################################################















    //################################################## 公用验证区域 start ##################################################
    public void putAllHashBound(String key, Map<String, Object> map){
        redisTemplate.boundHashOps(key).putAll(map);
        //redisTemplate.boundHashOps(key).hasKey()
    }
    //################################################## 公用验证区域 end ####################################################

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值