Skip to content

集成RedisTemplate实现缓存操作

在Spring Boot中集成Redis并使用RedisTemplate进行缓存操作是一个常见的需求。

步骤1:添加依赖

首先,你需要在你的pom.xml文件中添加Spring Boot的Redis依赖:

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

步骤2:配置Redis

接下来,在你的application.propertiesapplication.yml文件中添加Redis的配置信息:

properties
# application.properties
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=
spring.redis.database=0

或者使用YAML格式:

yaml
# application.yml
spring:
  redis:
    host: localhost
    port: 6379
    password: 
    database: 0

步骤3:自定义RedisTemplate

通常情况下,Spring Boot会自动配置一个RedisTemplate,但为了更灵活地控制序列化方式,我们可能会需要自定义RedisTemplate

java
@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        
        // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
        Jackson2JsonRedisSerializer<Object> jacksonSeial = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jacksonSeial.setObjectMapper(om);
        
        // 使用StringRedisSerializer来序列化和反序列化redis的key值
        StringRedisSerializer stringSeial = new StringRedisSerializer();
        
        template.setKeySerializer(stringSeial);
        template.setValueSerializer(jacksonSeial);
        template.setHashKeySerializer(stringSeial);
        template.setHashValueSerializer(jacksonSeial);
        
        template.afterPropertiesSet();
        return template;
    }
}

步骤4:使用RedisTemplate

现在你可以在你的服务层中注入RedisTemplate来执行缓存操作了:

java
@Service
public class CacheService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    public void setCache(String key, Object value) {
        ValueOperations<String, Object> operations = redisTemplate.opsForValue();
        operations.set(key, value);
    }

    public Object getCache(String key) {
        ValueOperations<String, Object> operations = redisTemplate.opsForValue();
        return operations.get(key);
    }
}

事务操作

java
@Autowired
private StringRedisTemplate stringRedisTemplate;

public void executeRedisTransaction() {
    // 获取实际使用的连接
    RedisConnection connection = stringRedisTemplate.getConnectionFactory().getConnection();
    
    connection.multi(); // 开始事务
    
    try {
        // 执行一些Redis命令
        stringRedisTemplate.opsForValue().set("key1", "value1");
        stringRedisTemplate.opsForValue().increment("counter1");

        // 获取事务结果
        List<Object> results = connection.exec(); // 提交事务
        
        // 检查事务是否成功执行(可选)
        if (results.isEmpty()) {
            System.out.println("Transaction failed or was discarded.");
        } else {
            System.out.println("Transaction succeeded.");
        }
    } catch (Exception e) {
        connection.discard(); // 放弃事务
        System.out.println("Transaction discarded due to exception: " + e.getMessage());
    }
}

流水线操作

java
@Autowired
private StringRedisTemplate stringRedisTemplate;

public void executeRedisPipeline() {
    // 获取底层的RedisConnection
    RedisConnection connection = stringRedisTemplate.getConnectionFactory().getConnection();
    
    // 开始流水线
    List<Object> results = connection.openPipeline();

    try {
        // 执行一系列Redis命令
        stringRedisTemplate.opsForValue().set("key1", "value1");
        stringRedisTemplate.opsForValue().increment("counter1");
        stringRedisTemplate.opsForValue().set("key2", "value2");

        // 关闭流水线并获取结果
        results = connection.closePipeline();
        
        // 处理结果(如果需要)
        for (Object result : results) {
            System.out.println(result);
        }
    } finally {
        // 确保资源被正确释放
        if (connection != null) {
            connection.close();
        }
    }
}

Spring Data Redis

为了更加方便地使用流水线功能,Spring Data Redis提供了executePipelined方法,可以用来包装一系列操作

java
stringRedisTemplate.executePipelined(new RedisCallback<Object>() {
    @Nullable
    @Override
    public Object doInRedis(RedisConnection connection) throws DataAccessException {
        // 在这里执行一系列Redis命令
        connection.set("key1".getBytes(), "value1".getBytes());
        connection.incr("counter1".getBytes());
        connection.set("key2".getBytes(), "value2".getBytes());

        // 返回null,因为结果是由executePipelined方法处理的
        return null;
    }
});