开发者

Java连接并操作Redis超详细教程

目录
  • 引言
  • 1. Redis 基础概念与 Java 生态概览
    • 1.1 Redis 是什么?
    • 1.2 Java 操作 Redis 的核心场景
  • 2.Jedis 原生客户端:从直接连接到连接池
    • 2.0 Maven依赖
    • 2.1 Jedis 直接连接(非池化方式)
      • 2.1.1 核心代码解析
      • 2.1.2 核心类与对象
      • 2.1.3 原理分析
      • 2.1.4 优缺点
    • 2.2 Jedis 连接池(池化连接)
      • 2.2.1 连接池配置类
      • 2.2.2 连接池工作原理
      • 2.2.3 使用示例
      • 2.2.4 优势对比
  • 3. Spring Data Redis:高层抽象与模板化操作
    • 3.1 核心依赖与配置
      • 3.1.1 Maven 依赖
      • 3.1.2 YAML 配置
    • 3.2 RedisTemplate 核心类解析
      • 3.2.1 基础操作示例
      • 3.2.2 核心类结构
    • 3.3 序列化机制详解
      • 3.3.1 默认序列化问题
      • 3.3.2 jsON 序列化配置
      • 3.3.3 序列化流程
    • 3.4 对象存储实战(序列化配置后)
      • 3.4.1 User 实体类
      • 3.4.2 测试代码
      • 3.4.3 关键细节
  • 4. StringRedisTemplate:专注字符串场景
    • 4.1 基本概念
      • 4.2 对象操作实战
        • 4.2.1 测试代码
        • 4.2.2 核心步骤解析
      • 4.3 与 RedisTemplate 的对比
      • 5. 连接方式深度对比与选型建议
        • 5.1 技术维度对比
          • 5.2 场景化选型建议
            • 5.2.1 学习阶段
            • 5.2.2 小型项目(非 Spring)
            • 5.2.3 Spring Boot 项目
            • 5.2.4 纯字符串场景
          • 5.3 生产环境最佳实践
          • 6. 常见问题与解决方案
            • 6.1 连接失败问题
              • 6.2 数据乱码问题
                • 6.3 对象反序列化失败
                • 7. 扩展知识:异步客户端 Lettuce
                  • 7.1 Lettuce 简介
                    • 7.2 核心差异
                      • 7.3 配置示例
                      • 8. 总结:从入门到实战的成长路径
                        • 8.1 学习阶段建议
                          • 8.2 核心知识图谱
                            • 8.3 结语

                            引言

                            在分布式系统和高并发场景中,Redis 作为高性能内存数据库的地位举足轻重。对于 Java 开发者而言,掌握 Redis 的连接与操作是进阶必备技能。然而,从基础的 Jedis 原生客户端到 Spring 封装的 RedisTemplate,不同连接方式的原理与适用场景常让初学者困惑。如何选择合适的连接方式?序列化配置背后的逻辑是什么?生产环境中又该如何优化?

                            本文从 Java 操作 Redis 的核心需求出发,通过完整代码示例与逐行解析,系统讲解 Jedis 直接连接、连接池、RedisTemplate 及 StringRedisTemplate 的使用方法,深入剖析连接原理、序列化机制与性能优化策略。无论你是刚接触 Redis 的小白,还是需要规范项目实践的开发者,都能从代码细节与原理分析中获得启发,掌握从基础连接到高级应用的全流程实战技巧。

                            1. Redis 基础概念与 Java 生态概览

                            1.1 Redis 是什么?

                            Redis(Remote Dictionary Server)是一个基于内存的高性能键值对存储系统,具有以下核心特性:

                            • 数据结构丰富:支持 String、Hash、List、Set、Sorted Set 等 8 种数据结构
                            • 内存级性能:读写速度可达 10 万 + 次 / 秒(String 类型)
                            • 持久化支持:提供 RDB(快照)和 AOF(日志)两种持久化方式
                            • 集群能力:支持主从复制、哨兵模式、Cluster 集群
                            • 多语言支持:提供 Java、python、Node.js 等多语言客户端

                            在 Java 生态中,主流的 Redis 客户端包括:

                            • Jedis:官方提供的原生 Java 客户端,支持同步阻塞式 IO
                            • Lettuce:基于 Netty 的异步非阻塞客户端,支持响应式编程
                            • Spring Data Redis:Spring 封装的高层抽象,支持 Jedis/Lettuce 作为底层连接

                            1.2 Java 操作 Redis 的核心场景

                            • 缓存系统:降低数据库压力(如商品详情页缓存)
                            • 分布式会话:解决集群环境下的 Session 共享问题
                            • 计数器:实现点赞计数、接口限流等功能(利用 INCR 命令)
                            • 消息队列:基于 List 的 LPUSH/RPOP 实现简单队列
                            • 分布式锁:通过 SETNX 命令实现分布式锁机制

                            2.Jedis 原生客户端:从直接连接到连接池

                            2.0 Maven依赖

                            <!--        Jedis-->
                                    <dependency>
                                        <groupId>redis.clients</groupId>
                                        <artifactId>jedis</artifactId>
                                        <version>3.7.0</version>
                                    </dependency>
                            

                            2.1 Jedis 直接连接(非池化方式)

                            2.1.1 核心代码解析

                            @Slf4j
                            @SpringBootTest
                            public class JedisDirect {
                                private Jedis jedis;
                            
                                @BeforeEach
                                public void setUp(){
                                    //建立连接
                                    jedis = new Jedis("x.x.x.x",6379);
                            
                                    //设置密码
                                    jedis.auth("xxxx");
                            
                                    //选择库
                                    jedis.select(0);
                                }
                            
                                @Test
                                public void testString(){
                                    jedis.set("namePool","zhangsanPool");
                                    String value = jedis.get("name");
                                    log.info("value:"+value);
                                }
                            
                                @Test
                                public void testHash(){
                                    jedis.hset("user:2","name","lisiPool");
                                    jedis.hset("user:2","age","21");
                                    Map<String,String> map = jedis.hgetAll("user:1");
                            
                                     log.info("map:"+ map.toString());
                                }
                            
                            
                                @AfterEach
                                public void tearDown(){
                                    if(jedis != null){
                                        jedis.close();
                                    }
                                }
                            
                            
                            }
                            

                            代码的执行结果:

                            结果1:

                            Java连接并操作Redis超详细教程

                            结果2:

                            Java连接并操作Redis超详细教程

                            2.1.2 核心类与对象

                            Jedis:核心客户端类,封装了所有 Redis 命令

                            构造方法:Jedis(String host, int port) 初始化连接

                            常用方法:

                            • set(String key, String value):存储字符串
                            • get(String key):获取字符串
                            • hset(String key, String field, String value):存储 Hash 字段
                            • hgetAll(String key):获取 Hash 所有字段

                            @BeforeEach/@AfterEach:JUnit5 生命周期注解,分别用于初始化和销毁资源

                            2.1.3 原理分析

                            连接过程

                            • 创建 Jedis 实例时建立 TCP 连接(三次握手)
                            • 通过 auth 命令进行密码验证(如果配置了密码)
                            • select 命令选择操作的数据库(默认 0 号库)

                            命令执行

                            • 客户端将命令序列化为字节流发送到 Redis 服务器
                            • 服务器执行命令后返回结果,客户端解析响应

                            2.1.4 优缺点

                            • 优点:简单直观,适合学习和小规模测试
                            • 缺点
                              • 每次测试都创建新连接,性能低下(TCP 连接创建开销大)
                              • 并发场景下可能导致连接风暴
                              • 没有连接复用机制,资源利用率低

                            2.2 Jedis 连接池(池化连接)

                            2.2.1 连接池配置类

                            public class JedisConnectionFactory {
                                private static final JedisPool jedisPool;
                            
                                static{
                                    JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
                            
                                    //最大连接
                                    jedisPoolConfig.setMaxTotal(10);
                                    //最大空闲连接
                                    jedisPoolConfig.setMaxIdle(10);
                                    //最小空闲连接
                                    jedisPoolConfig.setMinIdle(5);
                            
                                    //设置最长等待时间
                                    jedisPoolConfig.setMaxWaitMillis(200);
                            
                                    jedisPool = new JedisPool(jedisPoolConfig,"x.x.x.x",6379,
                                            1000,"xxxx");
                            
                                }
                            
                                //获取jedis对象
                                public static Jedis getJedis(){
                                    return jedisPool.getResource();
                                }
                            }
                            

                            说明:

                            JedisPool:连接池核心类,管理连接的创建和回收

                            • getResource():从连接池获取可用连接(可能从空闲队列获取或新建)

                            JedisPoolConfig:连接池配置类,常用参数:

                            • maxTotal:最大连接数(控制并发量)
                            • maxIdle:最大空闲连接数(避免空闲连接过多)
                            • minIdle:最小空闲连接数(保证基础可用连接)

                            maxWaitMillis:获取连接超时时间(避免无限阻塞)

                            2.2.2 连接池工作原理

                            初始化阶段

                            • 启动时创建minIdle数量的空闲连php

                            获取连接

                            • 优先从空闲队列中获取连接
                            • 若空闲队列为空,且当前连接数小于maxTotal,则新建连接
                            • 若连接数已达maxTotal,则等待maxWaitMillis时间

                            归还连接

                            • 调用close()方法时,连接不会真正关闭,而是放回空闲队列
                            • 空闲连接数超过maxIdle时,多余连接会被销毁

                            2.2.3 使用示例

                            @Slf4j
                            @SpringBootTest
                            public class JedisPool {
                            
                                private Jedis jedis;
                            
                                @BeforeEach
                                public void setUp(){
                                    //建立连接
                                    jedis = JedisConnectionFactory.getJedis();
                            
                                    //设置密码
                                    jedis.auth("dhj20030916.");
                            
                                    //选择库
                                    jedis.select(0);
                                }
                            
                                @Test
                                public void testString(){
                                    jedis.set("name","zhangsan");
                                    String value = jedis.get("name");
                                    log.info("value:"+value);
                                }
                            
                                @Test
                                public void testHash(){
                                    jedis.hset("user:1","name","lisi");
                                    jedis.hset("user:1","age","21");
                                    Map<String,String> map = jedis.hgetAll("user:1");
                            
                                    log.info("map:"+ map.toString());
                                }
                            
                            
                                @AfterEach
                                public void tearDown(){
                                    if(jedis != null){
                                        jedis.close();
                                    }
                                }
                            }
                            
                            

                            运行结果:

                            结果1:

                            Java连接并操作Redis超详细教程

                            结果2:

                            Java连接并操作Redis超详细教程

                            2.2.4 优势对比

                            特性直接连接连接池方式
                            连接创建每次新建复用已有连接
                            并发支持好(控制连接数)
                            资源利用率
                            性能差(连接开销)好(减少握手)
                            适用场景单线程测试高并发生产环境

                            3. Spring Data Redis:高层抽象与模板化操作

                            3.1 核心依赖与配置

                            3.1.1 Maven 依赖

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

                            3.1.2 YAML 配置

                            spring:
                              redis:
                                host: x.x.x.x
                                port: 6379
                                password: xxxx
                                lettuce:
                                  pool:
                                    max-active: 10 #最大连接
                                    max-idle: 10   #最大空闲连接
                                    min-idle: 0    #最小空闲连接
                                    max-wait: 100  #连接等待时间
                            

                            3.2 RedisTemplate 核心类解析

                            3.2.1 基础操作示例

                            @SpringBootTest
                            @Slf4j
                            public class RedisTem {
                                @Autowired
                                private RedisTemplate redisTemplate;
                            
                                @Test
                                public void test(){
                            
                                    //插入一条String类型的数据
                                    redisTemplate.opsForValue().set("nameTem","赵六");
                                    Object s = redisTemplate.opsForValue().get("nameTem");
                                    log.info("nameTem:"+ s);
                                }
                            }
                            

                            运行结果:

                            Java连接并操作Redis超详细教程

                            3.2.2 核心类结构

                            RedisTemplate

                            泛型参数:<K, V> 分别表示键和值的类型

                            核心方法:

                            • opsForValue():获取字符串操作对象(对应 String 类型)
                            • opsForHash():获取 Hash 操作对象(对应 Hash 类型)
                            • opsForList():获取列表操作对象(对应 List 类型)
                            • opsForSet():获取集合操作对象(对应 Set 类型)
                            • opsForZSet():获取有序集合操作对象(对应 Sorted Set 类型)

                            RedisConnectionFactory

                            • 连接工厂接口,支持 Jedis/Lettuce 等多种实现
                            • Spring 自动根据依赖加载对应的实现(如引入 jedis 依赖则使用 JedisConnectionFactory)

                            3.3 序列化机制详解

                            3.3.1 默认序列化问题

                            Spring Data Redis 默认使用JdkSerializationRedisSerializer

                              • 序列化后数据冗余(包含类名、版本号等信息)
                              • 依赖类必须实现Serializable接口
                              • 跨语言不兼容(如 Python 无法解析 JDK 序列化数据)

                            3.3.2 JSON 序列化配置

                            @Configuration
                            public class RedisConfig {
                            
                                @Bean
                                public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
                            
                                    // 创建redisTemplate对象
                                    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
                            
                                    //设置连接工厂
                                    redisTemplate.setConnectionFactory(connectionFactory);
                            
                                    // 创建json序列化工具
                                    GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
                                    //设置Key的序列化
                                    redisTemplate.setKeySerializer(RedisSerializer.string());
                                    redisTemplate.setHashKeySerializer(RedisSerializer.string());
                                    //设置value的序列化
                                    redisTemplate.setValueSerializer(jsonRedisSerializer);
                                    redisTemplate.setHashValueSerializer(jsonRedisSerializer);
                            
                                    return redisTemplate;
                            
                                }
                            }
                            

                            3.3.3 序列化流程

                            存储数据

                            • 值对象(如 User 对象)通过 JSON 序列化工具转为 JSON 字符串
                            • 键和 Hash 键通过 String 序列化转为字节数组

                            读取数据

                            • 从 Redis 获取字节数组后,键反序列化为 String
                            • 值反序列化为对应的对象(通过 Jackson 的类型推断)

                            3.4 对象存储实战(序列化配置后)

                            3.4.1 User 实体类

                            @Data
                            public class User {
                                private Integer id;
                                private String name;
                                private Integer age;
                            }
                            

                            3.4.2 测试代码

                            @SpringBootTest
                            @Slf4j
                            public class RedisTemSer {
                                @Autowired
                                private RedisTemplate redisTemplate;
                            
                                @Test
                                public void testString(){
                                    redisTemplate.opsForValue().set("nameTemSer","test");
                                    String value = (String)redisTemplate.opsForValue().get("nameTemSer");
                                    log.info("value"+ value);
                                }
                            
                                @Test
                                public void testHash(){
                                    redisTemplate.opsForHash().put("user:3","name","hash");
                                    redisTemplate.opsForHash().put("user:3","age","22");
                                    Map<String,Object> map = (Map<String,Object>)redisTemplate.opsForHash().entries("user:3");
                                    log.info("map"+ map);
                                }
                            
                                @Test
                                public void testObject(){
                                    User user = new User();
                                    user.setId(1);
                                    user.setName("object");
                                    user.setAge(20);
                            
                                    redisTemplate.opsForValue().set("User",user);
                            
                                    Object object = redisTemplate.opsForValue().get("User");
                                    log.info("object"+ object);
                                }
                            
                            }
                            

                            运行结果:

                            结果1:

                            Java连接并操作Redis超详细教程

                            结果2:

                            Java连接并操作Redis超详细教程

                            结果3:

                            Java连接并操作Redis超详细教程

                            3.4.3 关键细节

                            类型转换

                            • opsForValue().set(key, value) 支持任意对象,内部自动序列化
                            • opsForValue().get(key) 返回 Object 类型,需手动强转(依赖序列化配置)

                            Hash 操作

                            • opsForHash().put(key, field, value) 存储 Hash 字段,value 自动序列化
                            • entries() 方法返回 Map<String, Object>,字段值已反序列化

                            4. StringRedisTemplate:专注字符串场景

                            4.1 基本概念

                            StringRedisTemplateRedisTemplate<String, String> 的子类

                            默认配置:

                            • 键序列化:StringRedisSerializer(等同于RedisSerializer.string()
                            • 值序列化:StringRedisSerializer(直接存储字符串)

                            4.2 对象操作实战

                            4.2.1 测试代码

                            @Slf4j
                            @SpringBootTest
                            public class StringRedisTem {
                                @Autowired
                                private StringRedisTemplate stringRedisTemplate;
                            
                                private static final ObjectMapper mapper = new ObjectMapper();
                            
                                @Test
                                public void testObject() throws JsonProcessingException {
                                    User user = new User();
                                    user.setId(2);
                                    user.setName("StringRedisTem");
                                    user.setAge(20);
                            
                                    // 手动序列化value
                                    String json = mapper.writeValueAsString(user);
                                    stringRedisTemplate.opsForValue().set("UserRedis", json);
                            
                                    // 获取数据
                                    String val = stringRedisTemplate.opsForValue().get("UserRedis");
                            
                                    // 手动反序列化
                                    User userValue = mapper.readValue(val,User.class);
                                    log.info(userValue.toString());
                                }
                            
                            
                            }
                            

                            运行结果:

                            Java连接并操作Redis超详细教程

                            4.2.2 核心步骤解析

                            序列化

                            • 使用 Jackson 的ObjectMapper将 User 对象转为 JSON 字符串
                            • 解决StringRedisTemplate只能存储字符串的限制

                            存储与获取

                            • opsForValue().set(key, value) 直接存储字符串
                            • opsForValue().get(key) 直接获取字符串

                            反序列化

                            • 将获取的 JSON 字符串转为js User 对象
                            • 需要处理可能的JsonProcessingException异常

                            4.3 与 RedisTemplate 的对比

                            特性RedisTemplateStringRedisTemplate
                            泛型参数<K, V> 任意类型<String, String>
                            序列化支持自定义序列化固定 String 序列化
                            对象操作自动序列化 / 反序列化需手动序列化 / 反序列化
                            键类型任意类型(需序列化)只能是 String 类型
                            适用场景复杂数据类型(对象、Hash 等)纯字符串场景(如缓存文本)

                            5. 连接方式深度对比与选型建议

                            5.1 技术维度对比

                            维度Jedis 直接连接Jedis 连接池RedisTemplateStringRedisTemplate
                            连接管理手动创建连接池管理框架管理框架管理
                            序列化支持无(需手动)支持自定义仅 String 序列化
                            Spring 集成强(自动装配)强(自动装配)
                            学习成本
                            并发性能

                            5.2 场景化选型建议

                            5.2.1 学习阶段

                            推荐使用 Jedis 直接连接

                            • 代码简单,便于理解 Redis 基本操作
                            • 适合单个命令测试(如 GET/SET/HSET 等)

                            5.2.2 小型项目(非 Spring)

                            推荐 Jedis 连接池

                            • 避免频繁创建连接,提升性能
                            • 手动管理连接,适合轻量级项目

                            5.2.3 Spring Boot 项目

                            优先使用 RedisTemplate

                            • 与 Spring 生态无缝集成(依赖注入、配置管理)
                            • 支持复杂数据类型和自定php义序列化
                            • 推荐配置 JSON 序列化,兼容对象存储

                            5.2.4 纯字符串场景

                            使用 StringRedisTemplate

                            • 简化字符串操作(避免泛型转换)
                            • 性能略优(减少序列化层开销)

                            5.3 生产环境最佳实践

                            连接池配置

                            • maxTotal设置为系统并发量的 1.5-2 倍
                            • maxWaitMillis不超过 200ms(避免过长阻塞)
                            • minIdle设置为 5-10(保证基础连接可用性)

                            序列化选择

                            • 统一使用 JSON 序列化(GenericJackson2JsonRedisSerializer
                            • 键使用 String 序列化(保证可读性和可维护性)

                            异常处理

                            • 添加try-catch-finally块,确保连接归还
                            • 处理JedisConnectionException等网络异常

                            监控与调优

                            • 监控连接池的空闲连接数、活跃连接数
                            • 使用 Redis 的INFO connection命令查看服务器连接状态

                            6. 常见问题与解决方案

                            6.1js 连接失败问题

                            现象:

                            • 抛出JedisConnectionException: ``java.net``.ConnectException: Connection refused

                            可能原因:

                            • Redis 服务器未启动
                            • IP python地址或端口错误(检查配置中的 host 和 port)
                            • 防火墙阻止连接(需开放 6379 端口)
                            • Redis 密码错误(auth 命令失败)

                            解决方案:

                            • 确保 Redis 服务器正常运行(redis-cli ping检查连通性)
                            • 核对配置中的连接参数(IP、端口、密码)
                            • 检查服务器防火墙设置(如 linux 的firewall-cmd

                            6.2 数据乱码问题

                            现象:

                            Redis 存储的字符串在 Java 中获取时出现乱码

                            可能原因:

                            • 未正确设置字符编码(Jedis 默认使用 UTF-8)
                            • 序列化方式不匹配(如 RedisTemplate 使用 JDK 序列化,手动使用字符串读取)

                            解决方案:

                            Jedis 中指定编码:

                            jedis.get("key", StandardCharsets.UTF\_8); // 显式指定编码

                            RedisTemplate 统一使用 String 序列化:

                            template.setKeySerializer(RedisSerializer.string());

                            6.3 对象反序列化失败

                            现象:

                            • 从 Redis 获取对象时抛出ClassNotFoundException

                            可能原因:

                            • 使用 JDK 序列化时,类路径不一致(如部署环境类缺失)
                            • JSON 序列化时,对象缺少无参构造函数(Jackson 需要)

                            解决方案:

                            • 改用 JSON 序列化(避免类路径问题)
                            • 确保实体类包含无参构造函数(Lombok 的@Data默认生成)

                            7. 扩展知识:异步客户端 Lettuce

                            7.1 Lettuce 简介

                            • 基于 Netty 的异步非阻塞客户端
                            • 支持响应式编程(Reactor 模式)
                            • 适合高并发、高吞吐量场景

                            7.2 核心差异

                            特性JedisLettuce
                            IO 模型同步阻塞异步非阻塞
                            连接方式每个线程一个连接单个连接处理多个请求
                            线程安全非线程安全线程安全
                            适用场景简单同步场景异步 / 反应式场景

                            7.3 配置示例

                            spring:
                              redis:
                                host: 1.94.22.150
                                port: 6379
                                password: dhj20030916.
                                lettuce:
                                  pool:
                                    max-active: 10 #最大连接
                                    max-idle: 10   #最大空闲连接
                                    min-idle: 0    #最小空闲连接
                                    max-wait: 100  #连接等待时间
                            

                            8. 总结:从入门到实战的成长路径

                            8.1 学习阶段建议

                            • 基础操作:掌握 Jedis 直接连接,理解 Redis 基本命令(SET/GET/HSET 等)
                            • 性能优化:学习连接池原理,掌握 JedisPool 配置与使用
                            • 框架集成:深入 Spring Data Redis,学会配置 RedisTemplate 和序列化
                            • 实战提升:在项目中应用缓存、分布式锁等场景,处理实际问题

                            8.2 核心知识图谱

                            Java连接并操作Redis超详细教程

                            8.3 结语

                            通过本文的系统学习,读者应能熟练掌握 Java 操作 Redis 的主流方式,理解不同连接方式的适用场景和底层原理,并能够在实际项目中根据需求选择合适的技术方案。记住,实践是最好的老师,建议通过实际项目练习加深理解,遇到问题时结合官方文档和源码进行分析,逐步提升 Redis 开发与运维能力。

                            以上就是Java连接并操作Redis超详细教程的详细内容,更多关于Java连接并操作Redis的资料请关注编程客栈(www.devze.com)其它相关文章!

                            0

                            上一篇:

                            下一篇:

                            精彩评论

                            暂无评论...
                            验证码 换一张
                            取 消

                            最新开发

                            开发排行榜