springboot集成redis

小助手 1年前 ⋅ 857 阅读

小Hub领读:

StringRedisTemplate和RedisTemplate有啥不同?


前言

Redis是个高性能的K-V缓存中间件,在一些分布式场景中,可以实现多个服务之间的数据共享,并且因为容易搭建高可用的主从或集群结构,因此被广泛使用。

学习Redis,你需要懂得的知识如下:

  • Redis的五大数据类型以及常用使用场景
  • Redis的主从结构,哨兵机制
  • Redis分布式锁如何实现
  • 单线程的Redis为什么这么快?(新版本已经不是单线程了)
  • 如何解释多路复用机制
  • Redis的过期策略,内存淘汰机制

小小Redis,居然要学这么多,慢慢来吧,今天,我们就只来谈谈Springboot如何集成redis,相信有些人已经会了,当不妨来也巩固一下知识点。

Redis相关的内容,我会持续写作并发布,同学们注意置顶【MarkerHub】哈,第一时间接收内容。

集成步骤

Springboot版本:2.2.2.RELEASE

集成三步走

springboot作为一个微服务框架,及简单集成其他框架,基本上步骤相似。

  • 首先maven导入相关jar包
  • 然后编写预定配置
  • @EnableXXX实现手动装配

当然了,有些框架并不需要@EnableXXX实现手动装配,因为已经实现了自动装配,不懂Springboot手动装配和自动装配的看看这篇文章。XXX

所以集成redis步骤如下:

1、导入jar包,也可在新建项目的时候勾选Spring Data Redis,就会自动加上。

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

2、编写配置,一般默认url就是localhost,端口6379,无密码。所以如果是本机的redis的话,可以省略编写配置,但为了以后上线可能修改,还是写上较好。

spring:
  redis:
    host: localhost
    port: 6379
    password:
    database: 0

当然了,这里还有很多关于redis的优化配置项,可以自己根据实际需求调整:

# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=20
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=10
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=1000

这时候,因为Springboot自动配置,redis就已经集成到项目中了。

我们可以使用的Redis操作工具类有两个:

  • StringRedisTemplate
  • RedisTemplate

两者的区别最大应该在这里:

  • 两者的数据是不共通的
  • StringRedisTemplate默认采用的是String的序列化策略StringRedisSerializer
  • RedisTemplate默认采用的是JDK的序列化策略JdkSerializationRedisSerializer
  • StringRedisTemplate只能对key=String,value=String的键值对进行操作,RedisTemplate可以对任何类型的key-value键值对操作

3、一般使用RedisTemplate进行数据操作。常用的接口如下:

redisTemplate.opsForValue();//操作字符串
redisTemplate.opsForHash();//操作hash
redisTemplate.opsForList();//操作list
redisTemplate.opsForSet();//操作set
redisTemplate.opsForZSet();//操作有序set

测试过程:

当然了,直接使用RedisTemplate有时候不太方便,一般我们都会使用一个util工具类来封装一下,这个工具类的代码太多,我就不贴全部代码了,可以找这个链接:https://github.com/MarkerHub/eblog/blob/master/src/main/java/com/example/util/RedisUtil.java

@Component
public class RedisUtil {

    @Autowired
    private RedisTemplate redisTemplate;
    
    /**
     * 指定缓存失效时间
     *
     * @param key  键
     * @param time 时间(秒)
     * @return
     */
    public 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;
        }
    }

    ....
}

改变序列化策略

对象存储到redis中是需要经过序列化的过程的,这也是我们为什么需要让对象实现序列化接口Serializable的原因,那改变序列化策略又是为了啥呢?

  • 默认序列化方式存储到redis的数据人工不可读
  • 不同策略序列化的过程有性能高低的

当然了,更多时候我们考虑的都是redis数据的可读性,因此,我们都把redis的序列化改成json或者string可读性比较强的方式。

我们先来比较一下StringRedisTemplate和RedisTemplate的序列化结果:

StringRedisTemplate序列化:

RedisTemplate序列化:

可以看出,从可读性上来讲,我们使用StringRedisTemplate操作的数据,在redis中明显更加清晰可读。

1、有哪些序列化器?

  • GenericToStringSerializer:

可以将任何对象泛化为字符串并序列化

  • Jackson2JsonRedisSerializer:

跟JacksonJsonRedisSerializer实际上是一样的

  • JacksonJsonRedisSerializer:

序列化object对象为json字符串

  • JdkSerializationRedisSerializer:

序列化java对象(被序列化的对象必须实现Serializable接口)

  • StringRedisSerializer:

简单的字符串序列化

  • GenericToStringSerializer:

类似StringRedisSerializer的字符串序列化

  • GenericJackson2JsonRedisSerializer:

类似Jackson2JsonRedisSerializer,但使用时构造函数不用特定的类参考以上序列化,自定义序列化类; 

推荐使用:

得根据场景,一般我key使用StringRedisSerializer,value使用GenericJackson2JsonRedisSerializer。

2、如何修改序列化器?

可以通过重写redisTemplate的属性改变默认序列化策略。

@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
    RedisTemplate<String, Object> template = new RedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);

    Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<Object>(Object.class);

    ObjectMapper objectMapper = new ObjectMapper();
    objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
    objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
    serializer.setObjectMapper(objectMapper);

    template.setKeySerializer(new StringRedisSerializer());
    template.setValueSerializer(serializer);

    template.setHashKeySerializer(new StringRedisSerializer());
    template.setHashValueSerializer(serializer);

    template.afterPropertiesSet();
    return template;
}

测试RedisTemplate序列化效果如下:

结束语

ok,今天的文章就到此就是啦。


全部评论: 0

    我有话说: