SpringBoot整合Redis使用

SpringDataRedis中的RedisTemplate介绍

maven依赖:

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

默认使用的是lettuce作为redis的客户端,Spring Data Redis封装了其API,RedisTemplate是它的核心类。引入commons-pool2的原因是 lettuce 需要使用 commons-pool 2 创建 Redis 连接池。

Spring Data Redis通过LettuceConnection来操作Redis,而这个对象通过LettuceConnectionFactory获得,因为letture可以帮我们创建连接池,我们也不需要关注创建连接池部分,需要关注的是LettuceConnectionConfiguration中的配置信息。(如果是Jedis就得我们手动代码创建线程池了)

序列化器

可以通过Redis来存取对象,实际上是RedisTemplate通过序列化器RedisSerializer进行了序列化。

SpringBoot整合Redis使用

RedisSerializer有两个主要方法:serialize(序列化)和deserialize(反序列化)。这里JdkSerializationRedisSerializer是RedisTemplate默认的序列化器,基本用的就是jdk序列化的方法,jdk中的序列化可以看我以前的文章对象的输入输出-java序列化机制

RedisTemplate可以配置它使用的序列化器,如下表

属性 描述 备注
defaultSerializer 默认序列化器 如果没有设置,则使用JdkSerializationRedisSerializer
keySerializer Redis键序列化器 如果没有设置,则使用默认序列化器
valueSerializer Redis值序列化器 如果没有设置,则使用默认序列化器
hashKeySerializer Redis散列结构field序列化器 如果没有设置,则使用默认序列化器
hashValueSerializer Redis散列结构value序列化器 如果没有设置,则使用默认序列化器
stringSerializer 字符串序列化器 RedisTemplate自动赋值为StringRedisSerializer对象

注意如果是使用默认的序列化器,在存键的时候RedisTemplate会把键也当成一个Java对象进行序列化,所以如果想RedisTemplate把键当成普通字符串,得配置为stringRedisSerializer。我们采用下面的注入方式:

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<Object,Object> redisTemplate = new RedisTemplate();
        // RedisTemplate会自动初始化StringSerializer,这里直接获取
        RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();

        // 设置字符串序列化器
        redisTemplate.setKeySerializer(stringRedisSerializer);
        redisTemplate.setHashKeySerializer(stringRedisSerializer);
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

或者,在springboot中,由于会自动注入RedisTemplate对象,可以在获取之后更改它的属性

@Autowired
private RedisTemplate redisTemplate = null;

@PostConstruct
public void init(){
    initRedisTemplate();
}

private void initRedisTemplate(){
    RedisSerializer stringRedisSerializer = redisTemplate.getStringSerializer();

    redisTemplate.setKeySerializer(stringRedisSerializer);
    redisTemplate.setHashKeySerializer(stringRedisSerializer);
}

对Redis数据类型操作的封装

操作接口 功能
GeoOperations 地理位置操作接口
HashOperations 散列操作接口
HyperLogLogOperations 基数操作接口
ListOperations 列表(链表)操作接口
SetOperations 集合操作接口
ValueOperations 字符串操作接口
ZSetOperations 有序集合操作接口

获取:

//字符串操作接口
ValueOperations valueOperations = redisTemplate.opsForValue();
SetOperations setOperations = redisTemplate.opsForSet();
HashOperations hashOperations = redisTemplate.opsForHash();
ListOperations listOperations = redisTemplate.opsForList();
ZSetOperations zSetOperations = redisTemplate.opsForZSet();

这些接口下的方法名就跟redis的操作指令一样了。需要注意的是在这些不同的接口中操作的实际上不是在同一个redis连接中完成的,默认每种类型的数据操作都使用了一条新连接。

RedisTemplate还可以绑定一个key,对这个key做连续的操作,如:

BoundValueOperations stringKeyOps = redisTemplate.boundValueOps("stringKey");

SessionCallback和RedisCallback

如果我们想在一个连接中执行多个Redis命令,就可能需要这两个接口,其中SessionCallback封装得更完善,推荐使用。

redisTemplate.execute(new SessionCallback() {
    @Override
    public Object execute(RedisOperations operations) throws DataAccessException {
        operations.opsForValue().set("key1","value1");
        operations.opsForHash().put("hash","field","hvalue");
        return null;
    }
});

SpringBoot中操作Redis

使用RedisTemplate

常用配置:

# 连接池中的最小空闲连接 默认 0
spring.redis.lettuce.pool.min-idle= 5
# 连接池最大连接数(使用负值表示没有限制) 默认 8
spring.redis.lettuce.pool.max-active= 10
# 连接池中的最大空闲连接 默认 8
spring.redis.lettuce.pool.max-idle= 10
# 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
spring.redis.lettuce.pool.max-wait= 2000

spring.redis.port=6379
spring.redis.host=127.0.0.1
spring.redis.password=
# Redis连接超时时间,单位毫秒
spring.redis.timeout= 1000

然后获取RedisTemplate就行了,这个是在IoC容器中的。

下面讲一种更简单的方法,Spring提供了缓存注解,使用这些注解可以有效简化编程过程。

缓存管理器

Spring支持多种缓存的使用,它提供了接口CacheManager,有许多实现类

SpringBoot整合Redis使用

在Spring Boot中,我们可以通过配置文件生成缓存管理器,如下:

# Spring Cache Start

# 默认情况下Spring会根据上下文探测
spring.cache.type=redis

# 缓存名称,配合注解使用
spring.cache.cache-names= redisCache

# 是否允许Redis缓存空值
spring.cache.redis.cache-null-values=true

# 是否启用Redis的键前缀
spring.cache.redis.use-key-prefix=true

# Redis的键前缀
spring.cache.redis.key-prefix=

# 缓存超时时间戳,配置为0则不设置超时时间
spring.cache.redis.time-to-live=0ms

# Spring Cache End

为了使用缓存管理器,首先在配置类中加入注解@EnableCaching

然后在Service层(而不是DAO层)的方法上加上如下注解:

  • @Cacheable 通常应用到读取数据的方法上,如查找方法:先从缓存中读取,如果没有再调用方法获取数据,然后把数据查询结果添加到缓存中。如果缓存中查找到数据,被注解的方法将不会执行。属性:
    • value:缓存的名称,这个是之前在配置文件中定义的spring.cache.cache-names
    • key:缓存的key,可以使用SpEL表达式,如key = "'redis_user_'+#id"
    • condition:缓存的条件,使用SpEL表达式,返回true则缓存
  • @CachePut 通常应用于保存和修改方法配置,能够根据方法的请求参数对其结果进行缓存,和 @Cacheable 不同的是,它每次都会触发被注解方法的调用。属性:
    • value:缓存的名称
    • key:缓存的key
    • condition:缓存的条件
  • @CachEvict 通常应用于删除方法配置,能够根据一定的条件对缓存进行清空。可以清除一条或多条缓存。属性:
    • value:缓存的名称
    • key:缓存的key
    • condition:缓存的条件
    • allEntries:是否清空所有缓存内容,默认为false
    • beforeInvocation:是否在方法执行前就清空,默认为false

原创文章,作者:彭晨涛,如若转载,请注明出处:https://www.codetool.top/article/springboot%e6%95%b4%e5%90%88redis%e4%bd%bf%e7%94%a8/

发表评论

电子邮件地址不会被公开。