Redis - springboot操作redis的简单demo

 springboot操作redis的简单demo

一丶在springboot项目pom.xml中引入spring-boot-starter-data-redis

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

 

 

二丶在application.properties中配置redisTemplate

## 位于spring-boot-autoconfigure-2.2.2.RELEASE.jar
## 对应于org.springframework.boot.autoconfigure.data.redis.RedisProperties属性
spring.redis.database=0
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=

 

以上配置对应于RedisProperties类

 

 

springboot会根据以下配置自动生成RedisTemplate实例, 一个是redisTemplate, 一个是stringRedisTemplate

 

 

  此时, 就可以直接使用redisTemplate操作redis了

 

三丶注意事项

  一般在java程序中, 使用的是java对象, 而redis存储的一般是字符串, 所以java程序和redis之间的交互需要转换数据格式, RedisTemplate中设置了 Serializer来做转换.

       RedisAutoConfiguration中构造的stringRedisTemplate, 默认key, value都是字符串

  RedisAutoConfiguration中构造的redisTemplate, 默认使用了JdkSerializationRedisSerializer, 保存的对象

需要实现Serializable接口, 否则会报错: DefaultSerializer requires a Serializable payload but received an object of type [xx.xx.xxxx类名], 如下

 

 

  在实际使用中, 本人偏向于序列化成json, 而不是使用jdk序列化, 这是因为json可读性更好, 容易排查bug, 而序列化json, 本人更喜欢使用fastjson

/**
     * 默认key是String, value是json
     * @param redisConnectionFactory
     * @return
     */
    @Bean("defaultRedisTemplate")
    public RedisTemplate<String,Object> defaultRedisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);


        //设置序列化
        RedisSerializer stringSerializer=new StringRedisSerializer();
        //本人偏好使用fastjson序列化成json
        RedisSerializer jsonSerializer=new GenericFastjson2JsonRedisSerializer();
        //官方提供jackson序列化成json
//        RedisSerializer jsonSerializer=new GenericJackson2JsonRedisSerializer();

        template.setKeySerializer(stringSerializer);
        template.setValueSerializer(jsonSerializer);

        template.setHashKeySerializer(stringSerializer);
        template.setHashValueSerializer(jsonSerializer);

        return template;
    }

 

四丶对redisTemplate的简单封装(不是最主要的, 可以不用)

   对redisTemplate的使用主要是对redis命令的使用, 熟悉命令即可,  命令想不起来时可以查看我的这篇文章

 

package com.ttx.redis.demo.manager;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.util.CollectionUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 对redis常用数据结构操作的简单封装
 * @author TimFruit
 * @date 19-12-27 下午10:13
 */
public class RedisManager<K,V> {

    private RedisTemplate<K,V> redisTemplate;

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

    public RedisTemplate<K, V> getRedisTemplate() {
        return redisTemplate;
    }


    // --------------------- key

    public void expireKey(K key, long timeout, TimeUnit unit){
        redisTemplate.expire(key, timeout, unit);
    }

    public void deleteKey(K key){
        redisTemplate.delete(key);
    }

    public void deleteKeyBatch(Collection<K> keys){
        redisTemplate.delete(keys);
    }





    //---------------------- string
    public void set(K key, V value){
        redisTemplate.opsForValue().set(key, value);
    }

    public void set(K key, V value, long timeout, TimeUnit unit){
        redisTemplate.opsForValue().set(key, value, timeout, unit);
    }

    public void setBatch(Map<K, V> kvMap){
        redisTemplate.opsForValue().multiSet(kvMap);
    }

    public V get(K key){
        return redisTemplate.opsForValue().get(key);
    }

    public Map<K, V>  getBatch(Collection<K> keys){

        List<V> values=redisTemplate.opsForValue().multiGet(keys);
        if(CollectionUtils.isEmpty(values)){
            return Collections.emptyMap();
        }

        // wrapper map
        Map<K,V> resultMap=new HashMap<>(keys.size());
        K key=null;
        V value=null;
        Iterator<K> keyIter=keys.iterator();
        Iterator<V> valueIter=values.iterator();
        while(keyIter.hasNext()){
            key=keyIter.next();
            value=valueIter.next();

            resultMap.put(key, value);
        }
        return resultMap;
    }





    //---------------------- list 左头右尾

    public void lLeftPush(K key, V value){
        redisTemplate.opsForList().leftPush(key, value);
    }

    public void lLeftPush(K key, V pivot, V value){
        redisTemplate.opsForList().leftPush(key, pivot, value);
    }

    public void lLeftPushBatch(K key, Collection<V> values){
        redisTemplate.opsForList().leftPushAll(key, values);
    }


    public void lRightPush(K key, V value){
        redisTemplate.opsForList().rightPush(key, value);
    }

    public void lRightPush(K key, V pivot, V value){
        redisTemplate.opsForList().rightPush(key, pivot, value);
    }

    public void lRightPushBatch(K key, Collection<V> values){
        redisTemplate.opsForList().rightPushAll(key, values);
    }



    public V lLeftPop(K key){
        return redisTemplate.opsForList().leftPop(key);
    }

    public V lRightPop(K key){
        return redisTemplate.opsForList().rightPop(key);
    }


    /**
     * 批量查询(不删除) 下标从左到右递增
     * @param key
     * @param start 0 表示第一个
     * @param stop -1 表示最后一个
     * @return
     */
    public List<V> lRange(K key, long start, long stop){
        return redisTemplate.opsForList().range(key, start, stop);
    }


    /**
     * 保留[start, stop]下标范围的队列,裁剪删除其他  (可以用作批量删除)
     * @param key
     * @param start
     * @param stop
     */
    public void lTrim(K key, long start, long stop){
        redisTemplate.opsForList().trim(key, start, stop);
    }

    public Long lSize(K key ){
        return redisTemplate.opsForList().size(key);
    }







    // ------------------------------- set

    public void sAdd(K key, V value){
        redisTemplate.opsForSet().add(key, value);
    }


    public void sAddBatch(K key, Collection<V> values){
        if(CollectionUtils.isEmpty(values)){
            return;
        }
        V[] valueArray=(V[])values.toArray();
        redisTemplate.opsForSet().add(key, valueArray);
    }

    public Set<V> sMembers(K key){
        return redisTemplate.opsForSet().members(key);
    }


    public V sRandomMember(K key){
        return redisTemplate.opsForSet().randomMember(key);
    }

    public Long sRemove(K key, V value){
        return redisTemplate.opsForSet().remove(key, value);
    }

    public Long sRemoveBatch(K key, Collection<V> values){
        if(CollectionUtils.isEmpty(values)){
            return 0L;
        }
        V[] valueArray=(V[])values.toArray();
        return redisTemplate.opsForSet().remove(key, valueArray);
    }

    public Boolean sIsMember(K key, V value){
        return redisTemplate.opsForSet().isMember(key, value);
    }

    public Long sSize(K key){
        return redisTemplate.opsForSet().size(key);
    }







    // ------------------------------- sorted set

    /**
     * 添加
     * @param key
     * @param value
     * @param score 分数
     * @return
     */
    public Boolean zAdd(K key,V value, double score){
        return redisTemplate.opsForZSet().add(key, value, score);
    }

    /**
     * 批量添加
     * @param key
     * @param tuples
     * @return
     */
    public Long zAddBatch(K key,Set<ZSetOperations.TypedTuple<V>> tuples){
        return redisTemplate.opsForZSet().add(key, tuples);
    }

    /**
     * 根据分数排序(从低到高)后的下标范围查询
     * @param key
     * @param start 0 表示第一个
     * @param stop -1 表示最后一个
     * @return
     */
    public Set<V> zRange(K key, long start, long stop){
        return redisTemplate.opsForZSet().range(key, start, stop);
    }


    /**
     * 根据分数排序(从高到低)后的下标范围查询
     * @param key
     * @param start 0 表示第一个
     * @param stop -1 表示最后一个
     * @return
     */
    public Set<V> zReverseRange(K key, long start, long stop){
        return redisTemplate.opsForZSet().reverseRange(key, start, stop);
    }



    /**
     * 根据分数排序(从低到高)后的下标范围查询
     * @param key
     * @param start 0 表示第一个
     * @param stop -1 表示最后一个
     * @return 结果带有分数
     */
    public Set<ZSetOperations.TypedTuple<V>> zRangeWithScores(K key, long start, long stop){
        return redisTemplate.opsForZSet().rangeWithScores(key, start, stop);
    }


    /**
     * 根据分数排序(从高到低)后的下标范围查询
     * @param key
     * @param start 0 表示第一个
     * @param stop -1 表示最后一个
     * @return 结果带有分数
     */
    public Set<ZSetOperations.TypedTuple<V>> zReverseRangeWithScores(K key, long start, long stop){
        return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, stop);
    }


    /**
     * (排序集合按照分数从低到高排序)
     * 根据分数范围[min, max]查询对应的结果
     * @param key
     * @param min
     * @param max
     * @return
     */
    public Set<V> zRangeByScores(K key, double min, double max){
        return redisTemplate.opsForZSet().rangeByScore(key, min, max);
    }

    /**
     * (排序集合按照分数从高到低排序)
     * 根据分数范围[min, max]查询对应的结果
     * @param key
     * @param min
     * @param max
     * @return
     */
    public Set<V> zReverseRangeByScores(K key, double min, double max){
        return redisTemplate.opsForZSet().reverseRangeByScore(key, min, max);
    }

    /**
     * (排序集合按照分数从低到高排序)
     * 根据分数范围[min, max]查询对应的结果
     * @param key
     * @param min
     * @param max
     * @return 结果带有分数
     */
    public Set<ZSetOperations.TypedTuple<V>> zRangeByScoresWithScores(K key, double min, double max){
        return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max);
    }

    /**
     * (排序集合按照分数从低到高排序)
     * 根据分数范围[min, max]查询对应的结果
     * @param key
     * @param min
     * @param max
     * @param offset 分页查询 偏移下标
     * @param count 分页查询 一页大小
     * @return 结果带有分数
     */
    public Set<ZSetOperations.TypedTuple<V>> zRangeByScoresWithScores(K key, double min, double max, int offset, int count){
        return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max, offset, count);
    }

    /**
     * (排序集合按照分数从高到低排序)
     * 根据分数范围[min, max]查询对应的结果
     * @param key
     * @param min
     * @param max
     * @return 结果带有分数
     */
    public Set<ZSetOperations.TypedTuple<V>> zReverseRangeByScoresWithScores(K key, double min, double max){
        return redisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, min, max);
    }

    /**
     * (排序集合按照分数从高到低排序)
     * 根据分数范围[min, max]查询对应的结果
     * @param key
     * @param min
     * @param max
     * @param offset 分页查询 偏移下标
     * @param count 分页查询 一页大小
     * @return 结果带有分数
     */
    public Set<ZSetOperations.TypedTuple<V>> zReverseRangeByScoresWithScores(K key, double min, double max, int offset, int count){
        return redisTemplate.opsForZSet().reverseRangeByScoreWithScores(key, min, max, offset, count);
    }

    /**
     * (排序集合按照分数从低到高排序)
     * 查询value的下标(排名)
     * @param key
     * @param value
     * @return 如果不存在,则返回null
     */
    public Long zRank(K key, V value){
        return redisTemplate.opsForZSet().rank(key, value);
    }

    /**
     * (排序集合按照分数从高到低排序)
     * 查询value的下标(排名)
     * @param key
     * @param value
     * @return 如果不存在,则返回null
     */
    public Long zReverseRank(K key, V value){
        return redisTemplate.opsForZSet().reverseRank(key, value);
    }

    /**
     * 查询value的分数
     * @param key
     * @param value
     * @return
     */
    public Double zScore(K key, V value){
        return redisTemplate.opsForZSet().score(key, value);
    }

    /**
     * 排序集合的个数
     * @param key
     * @return
     */
    public Long zSize(K key){
        return redisTemplate.opsForZSet().size(key);
    }

    /**
     * 统计指定分数范围[min, max]的个数
     * @param key
     * @param min
     * @param max
     * @return
     */
    public Long zCount(K key, double min, double max){
        return redisTemplate.opsForZSet().count(key, min, max);
    }

    /**
     * 删除指定值
     * @param key
     * @param value
     */
    public Long zRemove(K key, V value){
        return redisTemplate.opsForZSet().remove(key, value);
    }

    /**
     * 批量删除指定值
     * @param key
     * @param values
     * @return
     */
    public Long zRemoveBatch(K key, Collection<V> values){
        if(CollectionUtils.isEmpty(values)){
            return 0L;
        }
        V[] valueArray=(V[])values.toArray();
        return redisTemplate.opsForZSet().remove(key, valueArray);
    }

    /**
     * (排序集合按照分数从低到高排序)
     * 根据下标范围[start, stop]删除
     * @param key
     * @param start
     * @param stop
     * @return
     */
    public Long zRemoveRange(K key, long start, long stop){
        return redisTemplate.opsForZSet().removeRange(key, start, stop);
    }

    /**
     * 根据分数范围[min, max]删除
     * @param key
     * @param min
     * @param max
     * @return
     */
    public Long zRemoveRangeByScore(K key, double min, double max){
        return redisTemplate.opsForZSet().removeRangeByScore(key, min, max);
    }


    /**
     * 增加指定值的分数
     * @param key
     * @param value
     * @param delta
     * @return
     */
    public Double zIncrementScore(K key, V value, double delta){
        return redisTemplate.opsForZSet().incrementScore(key, value, delta);
    }







    // ------------------------------- hash

    /**
     * 在key对应的hash结构中, 添加hashKey, value
     * @param key
     * @param hashKey
     * @param value
     */
    public void hPut(K key, Object hashKey, Object value){
        redisTemplate.opsForHash().put(key, hashKey, value);
    }


    public void hPutAll(K key, Map hashMap){
        redisTemplate.opsForHash().putAll(key, hashMap);
    }

    /**
     * 在key对应的hash结构中, 查询hashKey对应的值
     * @param key
     * @param hashKey
     * @return
     */
    public Object hGet(K key, Object hashKey){
        return redisTemplate.opsForHash().get(key, hashKey);
    }

    /**
     * 在key对应的hash结构中, 批量查询hashKeys对应的值
     * @param key
     * @param hashKeys
     * @return
     */
    public Map hGetBatch(K key, Collection hashKeys){
        if(CollectionUtils.isEmpty(hashKeys)){
            return Collections.EMPTY_MAP;
        }

        List values=redisTemplate.opsForHash().multiGet(key, hashKeys);

        // wrap map
        Map resultMap=new HashMap(hashKeys.size());
        Object hashKey=null;
        Object value=null;

        Iterator hashKeyIter=hashKeys.iterator();
        Iterator valueIter=values.iterator();
        while(hashKeyIter.hasNext()){
            hashKey=hashKeyIter.next();
            value=valueIter.next();
            resultMap.put(hashKey, value);
        }
        return resultMap;
    }


    /**
     * 在key对应的hash结构中, 删除hashKey
     * @param key
     * @param hashKey
     * @return
     */
    public Long hDelete(K key, Object hashKey){
        return redisTemplate.opsForHash().delete(key, hashKey);
    }

    /**
     * 在key对应的hash结构中, 批量删除hashKeys
     * @param key
     * @param hashKeys
     * @return
     */
    public Long hDeleteBatch(K key, Collection hashKeys){
        if(CollectionUtils.isEmpty(hashKeys)){
            return 0L;
        }
        Object[] hashKeyArray=hashKeys.toArray();
        return redisTemplate.opsForHash().delete(key, hashKeyArray);
    }


    /**
     * 获取key对应hash结构中的所有hashKeys
     * @param key
     * @return
     */
    public Set hKeys(K key){
        return redisTemplate.opsForHash().keys(key);
    }

    /**
     * 获取key对应hash结构中的所有value
     * @param key
     * @return
     */
    public List hValues(K key){
        return redisTemplate.opsForHash().values(key);
    }

    /**
     * 判断hashKey是否在key对应的hash结构中
     * @param key
     * @param hashKey
     * @return
     */
    public Boolean hHasKey(K key, Object hashKey){
        return redisTemplate.opsForHash().hasKey(key, hashKey);
    }

    /**
     * 获取key对应的hash结构中数据个数
     * @param key
     * @return
     */
    public Long hSize(K key){
        return redisTemplate.opsForHash().size(key);
    }






}
View Code

 

  完整源码

posted @ 2020-01-02 00:14  timfruit  阅读(1535)  评论(0编辑  收藏  举报