SpringDataRedis快速入门教程

 更新时间:2026年04月17日 09:33:16   作者:難釋懷  
这篇文章主要介绍了SpringDataRedis快速入门教程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

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

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

  • 是否为每个 Redis 操作写重复的 try-finally 代码?
  • 是否希望像操作数据库一样,用声明式方式操作 Redis?
  • Spring Data Redis 正是为解决这些问题而生!

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

  • 自动管理连接(默认使用高性能 Lettuce 客户端)
  • 提供 RedisTemplate 和 StringRedisTemplate 简化操作
  • 支持序列化定制、事务、管道等高级特性
  • 无缝集成 Spring Cache,一行注解实现缓存

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

二、环境准备

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

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

  • Spring Web
  • Spring Data Redis (Access+Driver)

或手动添加 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);
    }
}

效果

  • 第一次调用 getUserById("1001") → 查询 DB 并缓存
  • 后续调用 → 直接返回缓存,不执行方法体

七、常见问题与避坑指南

坑 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

九、总结

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

相关文章

  • Netty学习之理解selector原理示例

    Netty学习之理解selector原理示例

    这篇文章主要为大家介绍了Netty学习之理解selector原理示例使用分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪<BR>
    2023-07-07
  • 详解使用JavaMailSender给曾经心爱的她再中秋发送一封特别的邮件

    详解使用JavaMailSender给曾经心爱的她再中秋发送一封特别的邮件

    网站的服务端向用户发邮件时,邮件中往往需要携带图片,链接等内容。所以为了方便起见,我们一般发送HTML格式的邮件,那么怎么去拼一个HTML格式的邮件呢?——Thymeleaf。开始之前,先新建一个SpringBoot项目,并添加需要用到的依赖。然后就可以继续往下了
    2022-09-09
  • Java实现浏览器大文件上传的示例详解

    Java实现浏览器大文件上传的示例详解

    文件上传是许多项目都有的功能,用户上传小文件速度一般都很快,但如果是大文件几个g,几十个g的时候,上传了半天,马上就要完成的时候,网络波动一下,文件又要重新上传,所以本文给大家介绍了Java实现浏览器大文件上传的示例,需要的朋友可以参考下
    2024-07-07
  • 深入理解 Java 中的 Switch 语句示例详解

    深入理解 Java 中的 Switch 语句示例详解

    在Java编程中,switch语句通过表达式值来执行不同代码块,本文介绍switch语法、案例、注意事项,以及与if语句的对比,包括基本语法、关键字、表达式、case常量、break和default的使用,以及如何根据输入的字符输出星期、大小写转换、成绩判断和季节判断等实际应用场景
    2024-10-10
  • Java Thread之Sleep()使用方法及总结

    Java Thread之Sleep()使用方法及总结

    这篇文章主要介绍了Java Thread之Sleep()使用方法及总结,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • Java接口和抽象类有什么区别

    Java接口和抽象类有什么区别

    这篇文章主要介绍了Java接口和抽象类有什么区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-12-12
  • MyBatis中的占位符入参全面详解

    MyBatis中的占位符入参全面详解

    这篇文章主要为大家介绍了MyBatis中的占位符全面详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • 使用spring boot开发时java对象和Json对象转换的问题

    使用spring boot开发时java对象和Json对象转换的问题

    这篇文章主要介绍了使用spring boot开发时java对象和Json对象转换的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • JAVA映射实体类对象和List使用详解

    JAVA映射实体类对象和List使用详解

    文章主要内容介绍Java中实体类对象与List的映射方法,核心代码示例展示了如何将单个对象和List映射到实体类中,作者分享了个人经验,并鼓励读者参考和点赞支持
    2026-01-01
  • Maven解决jar包版本冲突的4种方法详解

    Maven解决jar包版本冲突的4种方法详解

    这篇文章主要给大家介绍了关于Maven解决jar包版本冲突的4种方法代码,maven工程要导入jar包的坐标,就必须要考虑解决jar包冲突,文中介绍的非常详细,需要的朋友可以参考下
    2023-07-07

最新评论