Spring Boot整合Redis

POM依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <!-- 用于序列化 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.62</version>
    </dependency>
</dependencies>

配置文件application.yaml

一般初始化一个Spring Boot项目后默认配置文件application.properties格式,直接重命名为application.yaml,个人比较喜欢用这个格式。

server:
  port: 8888

# Redis相关配置
spring:
  redis:
    # 数据库 默认就是0
    database: 0
    # 主机IP
    host: 47.100.254.31
    # 端口
    port: 6379
    # 密码
    password: 9TR6aCyZEjxmGtUwup
    # 连接超时时间,单位毫秒
    timeout: 1000
    jedis:
      pool:
        # 连接池最大连接数(使用负值表示没有限制
        max-active: 600
        # 连接池中的最大空闲连接
        max-idle: 100
        # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: 1000
        # 连接池中的最小空闲连接
        min-idle: 0

创建一个FastJson序列化类

这里纯粹是个人爱好,一直都在用FastJson,习惯了,你也可以使用Spring Boot自带的JackSon或者谷歌出品的Gson

public class FastJsonRedisSerializer<T> implements RedisSerializer<T> {

    private Class<T> clazz;
    private static final byte[] EMPTY_ARRAY = new byte[0];
    private static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    public FastJsonRedisSerializer(Class<T> clazz) {
        this.clazz = clazz;
    }

    @Override
    public byte[] serialize(T t) throws SerializationException {
        if (t == null) {
            return EMPTY_ARRAY;
        }
        try {
            try {
                return JSONObject.toJSONString(t).getBytes(DEFAULT_CHARSET);
            } catch (Exception e) {
                return String.valueOf(t).getBytes(DEFAULT_CHARSET);
            }
        } catch (Exception e) {
            throw new SerializationException("无法写入Json:" + e.getMessage(), e);
        }
    }

    @Override
    @SuppressWarnings("unchecked")
    public T deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        try {
            String str = new String(bytes, DEFAULT_CHARSET);
            try {
                JSONObject json = JSONObject.parseObject(str);
                return JSONObject.toJavaObject(json, clazz);
            } catch (Exception e) {
                return (T) str;
            }
        } catch (Exception e) {
            throw new SerializationException("无法读取Json:" + e.getMessage(), e);
        }
    }
}

Redis配置类

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        // 初始化一个RedisTemplate 不配置序列化默认使用String
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        // Fastjson序列化
        FastJsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJsonRedisSerializer<>(Object.class);
        // 字符串系列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        redisTemplate.setValueSerializer(fastJsonRedisSerializer);
        redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
        // 开启事务
        redisTemplate.setEnableTransactionSupport(true);
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    @Bean(name = "redisUtil")
    public RedisUtil redisUtil(RedisTemplate<String, Object> redisTemplate) {
        RedisUtil redisUtil = new RedisUtil();
        redisUtil.setRedisTemplate(redisTemplate);
        return redisUtil;
    }
}

Redis工具类

其实这个东西封装好的方法一大堆,随便找一篇博文就可以使用,你也可以直接复制我的,基本的String,Hash,Set,List我都有封装好方法。这类封装大同小异,基本都相差不多,有一些我没有封装的可根据自己使用封装进去。

public class RedisUtil {

    private static RedisTemplate redisTemplate;

    public void setRedisTemplate(RedisTemplate redisTemplate) {
        RedisUtil.redisTemplate = redisTemplate;
    }

    /**
     * 指定缓存失效时间
     *
     * @param key  键
     * @param time 失效时间,单位秒
     * @return 返回true,添加成功,false添加失败
     * @date 2019/11/28 15:27
     */
    public static boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据key获取过期时间
     *
     * @param key 键
     * @return 返回0代表永久失效(单位秒)
     * @date 2019/11/28 15:29
     */
    public static long getExpire(String key) {
        return redisTemplate.getExpire(key);
    }

    /**
     * 判断指定key是否存在
     *
     * @param key 键
     * @return 返回true存在,返回false不存在
     * @date 2019/11/28 15:31
     */
    public static boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除指定的key
     *
     * @param keys 一个或多个键
     * @date 2019/11/28 15:33
     */
    @SuppressWarnings("unchecked")
    public static void del(String... keys) {
        if (keys != null && keys.length > 0) {
            if (keys.length == 1) {
                redisTemplate.delete(keys);
            } else {
                redisTemplate.delete(Arrays.asList(keys));
            }
        }
    }

    /**
     * 根据指定key获取value
     *
     * @param key 键
     * @return 返回value
     * @date 2019/11/28 15:35
     */
    public static Object get(String key) {
        if (key == null) {
            return null;
        }
        return redisTemplate.opsForValue().get(key);
    }

    /**
     * 根据指定key获取value(转换为指定类型)
     *
     * @param key 键
     * @return 返回指定类型数据
     * @date 2019/11/28 15:38
     */
    @SuppressWarnings("unchecked")
    public static <T> T hget(String key, Class<T> clazz) {
        Object obj = get(key);
        if (obj == null) {
            return null;
        }
        if (obj instanceof JSON) {
            return ((JSON) obj).toJavaObject(clazz);
        }
        return (T) obj;
    }

    /**
     * 存入指定的key,value
     *
     * @param key   键
     * @param value 值
     * @return true存入成功,false存入失败
     * @date 2019/11/28 15:40
     */
    public static boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 存入指定的key,value,并设置缓存时间
     *
     * @param key   键
     * @param value 值
     * @param time  时间 单位秒
     * @return
     * @date 2019/11/28 15:43
     */
    public static boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 指定key递增
     *
     * @param key   键
     * @param delta 因子(要增加多少)
     * @return 返回递增后的值
     * @date 2019/11/28 15:46
     */
    public static long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递归因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 指定key递减
     *
     * @param key   键
     * @param delta delta 因子(要减少多少)
     * @return 返回递减后的值
     * @date 2019/11/28 15:49
     */
    public static long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递归因子必须大于0");
        }
        return redisTemplate.opsForValue().decrement(key, delta);
    }

    /**
     * 根据指定的key和item获取value(一般叫大key和小key)
     *
     * @param key  键
     * @param item 项
     * @return 返回指定的值
     * @date 2019/11/28 15:51
     */
    public static Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }

    /**
     * 根据指定的key和item获取value(转换为指定类型)
     *
     * @param key   键
     * @param item  项
     * @param clazz 转换类
     * @return 返回指定类型
     * @date 2019/11/28 15:54
     */
    public static <T> T hget(String key, String item, Class<T> clazz) {
        Object obj = hget(key, item);
        if (obj == null) {
            return null;
        }
        if (obj instanceof JSON) {
            return ((JSON) obj).toJavaObject(clazz);
        }
        return (T) obj;
    }

    /**
     * 根据指定的key获取所有hash的键值
     *
     * @param key 键
     * @return 返回所有hash键值
     * @date 2019/11/28 15:56
     */
    public static Map<Object, Object> hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * 根据指定的key存储hashmap
     *
     * @param key 键
     * @param map 多个键值
     * @return true存入成功,false存入失败
     * @date 2019/11/28 15:58
     */
    public static boolean hmset(String key, Map<String, Object> map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据指定的key存储hashmap,设置过期时间
     *
     * @param key  键
     * @param map  多个键值
     * @param time 过期时间,单位秒
     * @return true存入成功,false存入失败
     * @date 2019/11/28 16:00
     */
    public static boolean hmset(String key, Map<String, Object> map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据指定key和item向指定hash插入数据
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @return true存入成功,false存入失败
     * @date 2019/11/28 16:02
     */
    public static boolean hset(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 据指定key和item向指定hash插入数据,并添加过期时间
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @param time  过期时间,单位秒
     * @return true存入成功,false存入失败
     * @date 2019/11/28 16:04
     */
    public static boolean hset(String key, String item, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据指定的key和item删除hash中的数据
     *
     * @param key   键
     * @param items 值
     * @date 2019/11/28 16:07
     */
    public static void hdel(String key, Object... items) {
        redisTemplate.opsForHash().delete(key, items);
    }

    /**
     * 根据指定的key和item判断hash中数据是否存在
     *
     * @param key  键
     * @param item 项
     * @return 存在返回true,失败返回false
     * @date 2019/11/28 16:08
     */
    public static boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }

    /**
     * 根据key获取set中的所有值
     *
     * @param key 键
     * @return 返回set集合
     * @date 2019/11/28 16:10
     */
    public static Set<Object> sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据指定的key和value查询在set中是否存在
     *
     * @param key   键
     * @param value 值
     * @return 返回true存在,返回false不存在
     * @date 2019/11/28 16:12
     */
    public static boolean sHasKey(String key, Object value) {
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据指定key在set中存入一个或多个key
     *
     * @param key    键
     * @param values 值,一个或多个
     * @return 返回成功个数
     * @date 2019/11/28 16:14
     */
    public static long sSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }


    /**
     * 根据指定key在set中存入一个或多个key
     *
     * @param key    键
     * @param time   过期时间,单位秒
     * @param values 值,一个或多个
     * @return 返回成功个数
     * @date 2019/11/28 16:17
     */
    public static long sSetAndTime(String key, long time, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0) {
                expire(key, time);
            }
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }

    /**
     * 根据指定key获取set缓存长度
     *
     * @param key 键
     * @return 返回长度
     * @date 2019/11/28 16:19
     */
    public static long sGetSetSize(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }

    /**
     * 根据指定的key移除set中的value
     *
     * @param key    键
     * @param values 值
     * @return 移除个数
     * @date 2019/11/28 16:20
     */
    public static long setRemove(String key, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }

    /**
     * 根据指定的key获取指定的setart和end之间的值
     *
     * @param key   键
     * @param start 开始
     * @param end   结束
     * @return 值
     * @date 2019/11/28 16:21
     */
    public static List<Object> lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据指定key获取list的长度
     *
     * @param key 键
     * @return 返回list长度
     * @date 2019/11/28 16:23
     */
    public static long lGetListSize(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }

    /**
     * 根据指定key和索引获取list中的值
     *
     * @param key   键
     * @param index 索引 index大于0. 0表头,1第二个元素;index小于0, -1 表尾,-2 倒数第二个元素;
     * @return 返回value
     * @date 2019/11/28 16:24
     */
    public static Object lGetIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据指定key存入list
     *
     * @param key   键
     * @param value 值
     * @return true存入成功,false存入失败
     * @date 2019/11/28 16:25
     */
    public static boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据指定key存入list,并指定过期时间
     *
     * @param key   键
     * @param value 值
     * @param time  过期时间,单位秒
     * @return true存入成功,false存入失败
     * @date 2019/11/28 16:27
     */
    public static boolean lSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据指定key存入list
     *
     * @param key   键
     * @param value list值
     * @return true存入成功,false存入失败
     * @date 2019/11/28 16:28
     */
    public static boolean lSet(String key, List<Object> value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据指定key存入list
     *
     * @param key   键
     * @param value list值
     * @param time  过期时间,单位秒
     * @return true存入成功,false存入失败
     * @date 2019/11/28 16:28
     */
    public static boolean lSet(String key, List<Object> value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据指定key和索引修改list中的数据
     *
     * @param key   键
     * @param index 索引
     * @param value 值
     * @return true修改成功,false修改失败
     * @date 2019/11/28 16:29
     */
    public static boolean lUpdateIndex(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据指定key移除指定数量的值
     *
     * @param key   键
     * @param count 数量
     * @param value 值
     * @return 移除个数
     * @date 2019/11/28 16:30
     */
    public static long lRemove(String key, long count, Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0L;
        }
    }
}

自定义全局返回结果类

纯粹的个人习惯,虽然是写个例子,但是也要统一格式的返回结果

public class Result implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 状态码
     */
    private int code;
    
    /**
     * 响应消息
     */
    private String message;
    
    /**
     * 响应数据
     */
    private Object data;

    public Result(int code, String message) {
        this.code = code;
        this.message = message;
    }

    public Result(int code, String message, Object data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    // 省略下面的Getter和Setter方法
}

创建一个Controller层进行测试

由于是测试就不每个方法都进行测试了

@RestController
@RequestMapping("/redis")
public class RedisController {

    @PostMapping("/set")
    public Result set(String key, String value) {
        boolean setStatus = RedisUtil.set(key, value);
        if (setStatus) {
            return new Result(200, "存入成功");
        }
        return new Result(-1, "存入失败");
    }

    @GetMapping("/get")
    public Result get(String key) {
        Object data = RedisUtil.get(key);
        return new Result(200, "获取成功", data);
    }
}

测试结果:

添加

查询

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×