java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringDataRedis快速入门

SpringDataRedis快速入门教程

作者:難釋懷

这篇文章主要介绍了SpringDataRedis快速入门教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

一、前言:为什么用 Spring Data Redis?

你是否还在手动管理 Jedis 连接池?

作为 Spring 官方提供的 Redis 集成模块,它:

本文将带你从零搭建项目,掌握核心 API,并写出优雅的 Redis 代码!

二、环境准备

1. 创建 Spring Boot 项目(2.7+ 或 3.x)

通过 start.spring.io 添加依赖:

或手动添加 Maven 依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 若使用 Spring Boot 3.x,无需额外引入 Lettuce -->

注意:Spring Boot 2.x 默认使用 Lettuce(非阻塞、线程安全),不再推荐 Jedis。

2. 启动本地 Redis

# 使用 Docker 快速启动
docker run -d --name redis -p 6379:6379 redis:7.0

三、基础配置:application.yml

spring:
  redis:
    host: localhost
    port: 6379
    password: ""          # 无密码留空
    database: 0
    timeout: 2000ms       # 连接超时
    lettuce:
      pool:
        max-active: 20    # 最大连接数
        max-idle: 10      # 最大空闲连接
        min-idle: 2       # 最小空闲连接
        max-wait: 2000ms  # 获取连接最大等待时间

Spring Boot 会自动配置 RedisConnectionFactory 和 RedisTemplate无需手动创建连接池

四、核心操作:RedisTemplate vs StringRedisTemplate

Spring Data Redis 提供两个核心模板类:

模板类Key/Value 类型适用场景
RedisTemplate<K, V>泛型(Object)存储 Java 对象(需序列化)
StringRedisTemplateString / String纯字符串操作(如验证码、计数器)

1. 使用 StringRedisTemplate(推荐初学者)

@RestController
public class RedisController {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @GetMapping("/set")
    public String set(@RequestParam String key, @RequestParam String value) {
        stringRedisTemplate.opsForValue().set(key, value, 10, TimeUnit.MINUTES);
        return "OK";
    }

    @GetMapping("/get")
    public String get(@RequestParam String key) {
        return stringRedisTemplate.opsForValue().get(key);
    }

    // Hash 操作
    @PostMapping("/user")
    public void saveUser(@RequestParam String userId, 
                         @RequestParam String name, 
                         @RequestParam Integer age) {
        stringRedisTemplate.opsForHash().put("user:" + userId, "name", name);
        stringRedisTemplate.opsForHash().put("user:" + userId, "age", age.toString());
    }

    // List 操作
    @PostMapping("/task")
    public void addTask(@RequestParam String task) {
        stringRedisTemplate.opsForList().leftPush("tasks", task);
    }
}

优点:API 清晰,opsForXxx() 对应 Redis 数据类型

2. 使用 RedisTemplate 存储 Java 对象

步骤 1:定义实体类

public class User implements Serializable {
    private String id;
    private String name;
    private int age;
    // getter/setter...
}

步骤 2:配置序列化方式(避免乱码)

@Configuration
public class RedisConfig {

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

        // 使用 Jackson 序列化对象(可读性强)
        Jackson2JsonRedisSerializer<Object> serializer = 
            new Jackson2JsonRedisSerializer<>(Object.class);
        
        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.activateDefaultTyping(mapper.getPolymorphicTypeValidator(), 
                                     ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);

        // 设置 key 和 value 的序列化方式
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);
        template.afterPropertiesSet();
        return template;
    }
}

步骤 3:操作对象

@Autowired
private RedisTemplate<String, Object> redisTemplate;

public void saveUser(User user) {
    redisTemplate.opsForValue().set("user:" + user.getId(), user, 1, TimeUnit.HOURS);
}

public User getUser(String id) {
    return (User) redisTemplate.opsForValue().get("user:" + id);
}

提示:若不配置序列化,默认使用 JDK 序列化,会导致 Redis 中出现不可读的二进制数据。

五、常用操作速查表

操作代码示例
StringopsForValue().set("k", "v")
HashopsForHash().put("user:1", "name", "张三")
ListopsForList().rightPush("queue", "item")
SetopsForSet().add("tags", "java", "redis")
ZSetopsForZSet().add("rank", "playerA", 95.5)
过期时间expire("key", 60, TimeUnit.SECONDS)
批量操作opsForValue().multiSet(map)

六、进阶:结合 Spring Cache 实现声明式缓存

只需三步,方法结果自动缓存!

1. 启用缓存

@SpringBootApplication
@EnableCaching // ← 关键注解
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

2. 在 Service 方法上加注解

@Service
public class UserService {

    @Cacheable(value = "users", key = "#id")
    public User getUserById(String id) {
        System.out.println("查询数据库..."); // 仅首次打印
        return userMapper.selectById(id);
    }

    @CacheEvict(value = "users", key = "#id")
    public void updateUser(User user) {
        userMapper.update(user);
    }
}

效果

七、常见问题与避坑指南

坑 1:Redis 中出现\xac\xed\x00\x05乱码

原因:使用了默认的 JDK 序列化

解决:配置 StringRedisSerializer 或 Jackson2JsonRedisSerializer

坑 2:缓存穿透(大量查不存在的 key)

方案:对 null 结果也缓存(短 TTL),或使用布隆过滤器

坑 3:缓存雪崩(大量 key 同时过期)

方案:设置随机过期时间,如 600 + random(60)

八、Jedis vs Lettuce vs Spring Data Redis

方案适用场景
原生 Jedis学习 Redis 协议、极简项目
JedisPool需要精细控制连接池的中小项目
Spring Data Redis (Lettuce)✅ 主流选择:Spring Boot 项目、高并发、响应式支持

建议:新项目直接使用 Spring Data Redis + Lettuce

九、总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文