SpringBoot整合Redis

本文最后更新于2023.03.28-18:40,某些文章具有时效性,若有错误或已失效,请在下方留言或联系涛哥

什么是Redis?

Redis是一个基于内存可持久化键值对(key-value)模式的NoSQL数据库

优点

速度快(单线程,IO多路复用)、高性能、高可靠、可持久化(rdb,aof),支持丰富的数据结构

Redis应用场景

分布式锁

主要利用redis的setnx命令进行,setnx:“set if not exists”,如果不存在则成功

其他实现方式:数据库、zookeeper

分布式缓存

由于redis数据放在内存所以访问速度块、支持的数据类型比较丰富,所以redis很适合用来缓存数据
这里一般是做分布式缓存,本地缓存不需要用redis。
其他实现方式:自定义数据结构(例如java里的hashMap)

保存限时数据
redis中可以使用expire命令设置一个键的生存时间,到时间后redis会删除它。利用这一特性可以运用在限时的优惠活动信息、手机验证码等业务场景。

计数器相关问题

redis由于incrby命令可以实现原子性的递增,所以可以运用于高并发的秒杀活动、分布式序列号的生成、具体业务还体现在比如限制一个手机号发多少条短信、一个接口一分钟限制多少请求、一个接口一天限制调用多少次等等。

排行榜相关问题

关系型数据库在排行榜方面查询速度普遍偏慢,所以可以借助redis的SortedSet进行热点数据的排序。

消息中间件

数据库

整合案例

1,在pom.xml里导入依赖配置

<!--redis相关-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
            <version>1.4.7.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.79</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>

2,核心配置文件

application.yml

#Redis配置
  redis:  
    host: 127.0.0.1
    port: 6379
    #没用就填空
    password:
    jedis:
      pool:
        #连接池最大连接数
        max-active: 8
        #阻塞时间 (负表示没有)
        max-wait: -1
        #最大空闲连接
        max-idle: 8
        #最小空闲连接
        min-idle: 0
    #连接超时时间
    timeout: 30000

 3,创建config文件夹添加以下文件

RedisConfig.java

package com.xxgc.helloworld.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;

import java.lang.reflect.Method;
import java.time.Duration;

@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
        @Value("${spring.redis.host}")
        private String host;
        @Value("${spring.redis.port}")
        private int port;
        @Value("${spring.redis.timeout}")
        private int timeout;
        @Value("${spring.redis.password}")
        private String password;
        @Value("${spring.redis.jedis.pool.max-active}")
        private int maxActive;
        @Value("${spring.redis.jedis.pool.max-wait}")
        private int maxWait;
        @Value("${spring.redis.jedis.pool.max-idle}")
        private int maxIdle;
        @Value("${spring.redis.jedis.pool.min-idle}")
        private int minIdle;

        @Bean
        public KeyGenerator wiselyKeyGenerator(){
                return new KeyGenerator() {
                        @Override
                        public Object generate(Object target, Method method, Object... params) {
                                StringBuilder sb = new StringBuilder();
                                sb.append(target.getClass().getName());
                                sb.append(method.getName());
                                for (Object obj : params) {
                                        sb.append(obj.toString());
                                }
                                return sb.toString();
                        }
                };
        }

        @Bean
        public JedisConnectionFactory redisConnectionFactory() {
                JedisConnectionFactory factory = new JedisConnectionFactory();
                factory.setHostName(host);
                factory.setPort(port);
                factory.setTimeout(timeout); //设置连接超时时间
                factory.setPassword(password);
                factory.getPoolConfig().setMaxIdle(maxIdle);
                factory.getPoolConfig().setMinIdle(minIdle);
                factory.getPoolConfig().setMaxTotal(maxActive);
                factory.getPoolConfig().setMaxWaitMillis(maxWait);
                return factory;
        }

        // 管理缓存
        @Bean
        public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
                RedisCacheConfiguration redisCacheConfiguration = RedisCacheConfiguration.defaultCacheConfig()
                        .entryTtl( Duration.ofHours(1)); // 设置缓存有效期一小时
                return RedisCacheManager
                        .builder( RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory))
                        .cacheDefaults(redisCacheConfiguration).build();
        }

        @Bean
        public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
                StringRedisTemplate template = new StringRedisTemplate(factory);
                setSerializer(template); //设置序列化工具,这样ReportBean不需要实现Serializable接口
                template.afterPropertiesSet();
                return template;
        }

        private void setSerializer(StringRedisTemplate template) {
                Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
                ObjectMapper om = new ObjectMapper();
                om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
                om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
                jackson2JsonRedisSerializer.setObjectMapper(om);
                template.setValueSerializer(jackson2JsonRedisSerializer);
        }

}

 4,创建utils文件夹添加以下文件

RedisUtils.java

package com.xxgc.helloworld.utils;

import java.io.Serializable;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
/**
 * @Program: HelloWorld
 * @ClassName RedisUtils
 * @Description: Redis工具类
 * @Author: liutao
 * @DateTime: 2022/3/11 10:40
 * @Version: 1.0
 */
@Component
public class RedisUtils {
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 写入缓存
     *
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 写入缓存设置时效时间
     *
     * @param key
     * @param value
     * @return
     */
    public boolean set(final String key, Object value, Long expireTime, TimeUnit timeUnit) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            redisTemplate.expire(key, expireTime, timeUnit);
            result = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 批量删除对应的value
     *
     * @param keys
     */
    public void remove(final String... keys) {
        for (String key : keys) {
            remove(key);
        }
    }

    /**
     * 批量删除key
     *
     * @param pattern
     */
    public void removePattern(final String pattern) {
        Set<Serializable> keys = redisTemplate.keys(pattern);
        if (keys.size() > 0) {
            redisTemplate.delete(keys);
        }
    }

    /**
     * 删除对应的value
     *
     * @param key
     */
    public void remove(final String key) {
        if (exists(key)) {
            redisTemplate.delete(key);
        }
    }

    /**
     * 判断缓存中是否有对应的value
     *
     * @param key
     * @return
     */
    public boolean exists(final String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 读取缓存
     *
     * @param key
     * @return
     */
    public Object get(final String key) {
        Object result = null;
        ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
        result = operations.get(key);
        return result;
    }

    /**
     * 哈希 添加
     *
     * @param key
     * @param hashKey
     * @param value
     */
    public void hmSet(String key, Object hashKey, Object value) {
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        hash.put(key, hashKey, value);
    }

    /**
     * 哈希获取数据
     *
     * @param key
     * @param hashKey
     * @return
     */
    public Object hmGet(String key, Object hashKey) {
        HashOperations<String, Object, Object> hash = redisTemplate.opsForHash();
        return hash.get(key, hashKey);
    }

    /**
     * 列表添加
     *
     * @param k
     * @param v
     */
    public void lPush(String k, Object v) {
        ListOperations<String, Object> list = redisTemplate.opsForList();
        list.rightPush(k, v);
    }

    /**
     * 列表获取
     *
     * @param k
     * @param l
     * @param l1
     * @return
     */
    public List<Object> lRange(String k, long l, long l1) {
        ListOperations<String, Object> list = redisTemplate.opsForList();
        return list.range(k, l, l1);
    }

    /**
     * 集合添加
     *
     * @param key
     * @param value
     */
    public void add(String key, Object value) {
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        set.add(key, value);
    }

    /**
     * 集合获取
     *
     * @param key
     * @return
     */
    public Set<Object> setMembers(String key) {
        SetOperations<String, Object> set = redisTemplate.opsForSet();
        return set.members(key);
    }

    /**
     * 有序集合添加
     *
     * @param key
     * @param value
     * @param scoure
     */
    public void zAdd(String key, Object value, double scoure) {
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        zset.add(key, value, scoure);
    }

    /**
     * 有序集合获取
     *
     * @param key
     * @param scoure
     * @param scoure1
     * @return
     */
    public Set<Object> rangeByScore(String key, double scoure, double scoure1) {
        ZSetOperations<String, Object> zset = redisTemplate.opsForZSet();
        return zset.rangeByScore(key, scoure, scoure1);
    }
}

5,使用测试

package com.xxgc.helloworld.util;

import com.xxgc.helloworld.utils.RedisUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
/**
 * @Program: HelloWorld
 * @ClassName RedisUtilsTest
 * @Description: Redis测试类
 * @Author: liutao
 * @DateTime: 2022/3/11 12:19
 * @Version: 1.0
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisUtilsTest {
    @Autowired
    RedisUtils redisUtils;
    @Test
    public void test(){
        //往缓存设置值
        boolean a = redisUtils.set("name", 123456);
        System.out.println("a = " + a);
    }
    @Test
    public void test1(){
        Integer name = (Integer) redisUtils.get("name");
        System.out.println("name = " + name);
    }
}

效果

阅读剩余
THE END