springboot整合redis

目录

[1. 项目依赖 (pom.xml)](#1. 项目依赖 (pom.xml))

[2. 应用配置文件 (application.yml)](#2. 应用配置文件 (application.yml))

[3. Redis 配置类](#3. Redis 配置类)

[4. Redis 操作工具类](#4. Redis 操作工具类)

5.控制器类中的实际调用示例

6.测试工具类

7.启动类中的演示代码

8.使用示例说明

[1. Set 类型实际应用场景](#1. Set 类型实际应用场景)

[2. ZSet 类型实际应用场景](#2. ZSet 类型实际应用场景)

[3. Hash 类型实际应用场景](#3. Hash 类型实际应用场景)


下面是一个完整的 Spring Boot 项目示例,展示了如何使用 RedisTemplate 操作 Redis 的各种数据类型。

1. 项目依赖 (pom.xml)

复制代码
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.0</version>
        <relativePath/>
    </parent>
    
    <groupId>com.example</groupId>
    <artifactId>redis-demo</artifactId>
    <version>1.0.0</version>
    
    <properties>
        <java.version>1.8</java.version>
    </properties>
    
    <dependencies>
        <!-- Spring Boot Starter Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        
        <!-- Spring Boot Starter Data Redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        
        <!-- Redis客户端 Lettuce (默认) -->
        <dependency>
            <groupId>io.lettuce</groupId>
            <artifactId>lettuce-core</artifactId>
        </dependency>
        
        <!-- 对象序列化支持 -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
        
        <!-- Lombok 简化代码 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        
        <!-- 测试依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2. 应用配置文件 (application.yml)

复制代码
server:
  port: 8080

spring:
  redis:
    # Redis 服务器地址
    host: localhost
    # Redis 服务器端口
    port: 6379
    # Redis 数据库索引(默认为 0)
    database: 0
    # 连接超时时间
    timeout: 5000ms
    # 密码(如果没有密码则不配置)
    # password: yourpassword
    lettuce:
      pool:
        # 连接池最大连接数(使用负值表示没有限制)
        max-active: 8
        # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1ms
        # 连接池中的最大空闲连接
        max-idle: 8
        # 连接池中的最小空闲连接
        min-idle: 0

logging:
  level:
    com.example.redis: debug

3. Redis 配置类

复制代码
package com.example.redis.config;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    /**
     * 配置 RedisTemplate
     * 设置 key 和 value 的序列化方式
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        
        // 使用 Jackson2JsonRedisSerializer 序列化 value
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = 
                new Jackson2JsonRedisSerializer<>(Object.class);
        
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.activateDefaultTyping(
                LaissezFaireSubTypeValidator.instance,
                ObjectMapper.DefaultTyping.NON_FINAL
        );
        
        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
        
        // 使用 StringRedisSerializer 序列化 key
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        
        // key 采用 String 序列化
        template.setKeySerializer(stringRedisSerializer);
        // hash 的 key 也采用 String 序列化
        template.setHashKeySerializer(stringRedisSerializer);
        // value 采用 Jackson 序列化
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash 的 value 采用 Jackson 序列化
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        
        template.afterPropertiesSet();
        return template;
    }
}

4. Redis 操作工具类

复制代码
package com.example.redis.service;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class RedisService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // ============================== 通用操作 ==============================
    
    /**
     * 设置过期时间
     */
    public Boolean expire(String key, long time) {
        try {
            if (time > 0) {
                return redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return false;
        } catch (Exception e) {
            log.error("设置过期时间失败 key: {}, error: {}", key, e.getMessage());
            return false;
        }
    }

    /**
     * 获取过期时间
     */
    public Long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    /**
     * 判断 key 是否存在
     */
    public Boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            log.error("判断 key 是否存在失败 key: {}, error: {}", key, e.getMessage());
            return false;
        }
    }

    /**
     * 删除 key
     */
    public Boolean delete(String key) {
        try {
            return redisTemplate.delete(key);
        } catch (Exception e) {
            log.error("删除 key 失败 key: {}, error: {}", key, e.getMessage());
            return false;
        }
    }

    // ============================== String 操作 ==============================
    
    /**
     * 设置 String 类型值
     */
    public void setString(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            log.info("设置 String 成功 key: {}, value: {}", key, value);
        } catch (Exception e) {
            log.error("设置 String 失败 key: {}, error: {}", key, e.getMessage());
        }
    }

    /**
     * 设置 String 类型值并设置过期时间
     */
    public void setString(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                setString(key, value);
            }
            log.info("设置 String 成功 key: {}, value: {}, time: {}", key, value, time);
        } catch (Exception e) {
            log.error("设置 String 失败 key: {}, error: {}", key, e.getMessage());
        }
    }

    /**
     * 获取 String 类型值
     */
    public Object getString(String key) {
        try {
            Object value = redisTemplate.opsForValue().get(key);
            log.info("获取 String 成功 key: {}, value: {}", key, value);
            return value;
        } catch (Exception e) {
            log.error("获取 String 失败 key: {}, error: {}", key, e.getMessage());
            return null;
        }
    }

    /**
     * 递增
     */
    public Long increment(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 递减
     */
    public Long decrement(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().decrement(key, delta);
    }

    // ============================== List 操作 ==============================
    
    /**
     * 获取 list 缓存的内容
     */
    public List<Object> getList(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            log.error("获取 List 失败 key: {}, error: {}", key, e.getMessage());
            return null;
        }
    }

    /**
     * 获取 list 缓存的长度
     */
    public Long getListSize(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            log.error("获取 List 长度失败 key: {}, error: {}", key, e.getMessage());
            return 0L;
        }
    }

    /**
     * 通过索引获取 list 中的值
     */
    public Object getListByIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            log.error("通过索引获取 List 值失败 key: {}, index: {}, error: {}", 
                    key, index, e.getMessage());
            return null;
        }
    }

    /**
     * 将值放入 list 缓存(从右边添加)
     */
    public void rightPushList(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            log.info("List 右插入成功 key: {}, value: {}", key, value);
        } catch (Exception e) {
            log.error("List 右插入失败 key: {}, error: {}", key, e.getMessage());
        }
    }

    // ============================== Set 数据类型详细操作 ==============================
    
    /**
     * 向Set中添加多个元素(带过期时间)
     */
    public Long addToSetWithExpire(String key, long expireSeconds, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if (expireSeconds > 0) {
                redisTemplate.expire(key, expireSeconds, TimeUnit.SECONDS);
            }
            log.info("Set添加成功 key: {}, values: {}, count: {}, expire: {}秒", 
                    key, Arrays.toString(values), count, expireSeconds);
            return count;
        } catch (Exception e) {
            log.error("Set添加失败 key: {}, error: {}", key, e.getMessage());
            return 0L;
        }
    }

    /**
     * 获取Set中的所有元素(随机顺序)
     */
    public Set<Object> getAllSetMembers(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            log.error("获取Set所有元素失败 key: {}, error: {}", key, e.getMessage());
            return Collections.emptySet();
        }
    }

    /**
     * 随机获取Set中的一个元素
     */
    public Object getRandomSetMember(String key) {
        try {
            return redisTemplate.opsForSet().randomMember(key);
        } catch (Exception e) {
            log.error("随机获取Set元素失败 key: {}, error: {}", key, e.getMessage());
            return null;
        }
    }

    /**
     * 随机获取Set中的多个元素(可能重复)
     */
    public List<Object> getRandomSetMembers(String key, long count) {
        try {
            return redisTemplate.opsForSet().randomMembers(key, count);
        } catch (Exception e) {
            log.error("随机获取多个Set元素失败 key: {}, count: {}, error: {}", 
                    key, count, e.getMessage());
            return Collections.emptyList();
        }
    }

    /**
     * 随机移除并返回Set中的一个元素
     */
    public Object popRandomSetMember(String key) {
        try {
            Object member = redisTemplate.opsForSet().pop(key);
            log.info("弹出Set随机元素 key: {}, member: {}", key, member);
            return member;
        } catch (Exception e) {
            log.error("弹出Set随机元素失败 key: {}, error: {}", key, e.getMessage());
            return null;
        }
    }

    /**
     * 随机移除并返回Set中的多个元素
     */
    public List<Object> popRandomSetMembers(String key, long count) {
        try {
            List<Object> members = redisTemplate.opsForSet().pop(key, count);
            log.info("弹出多个Set随机元素 key: {}, members: {}", key, members);
            return members;
        } catch (Exception e) {
            log.error("弹出多个Set随机元素失败 key: {}, count: {}, error: {}", 
                    key, count, e.getMessage());
            return Collections.emptyList();
        }
    }

    /**
     * 获取两个Set的并集
     */
    public Set<Object> setUnion(String key1, String key2) {
        try {
            return redisTemplate.opsForSet().union(key1, key2);
        } catch (Exception e) {
            log.error("获取Set并集失败 key1: {}, key2: {}, error: {}", 
                    key1, key2, e.getMessage());
            return Collections.emptySet();
        }
    }

    /**
     * 获取多个Set的并集
     */
    public Set<Object> setUnion(Collection<String> keys) {
        try {
            return redisTemplate.opsForSet().union(keys);
        } catch (Exception e) {
            log.error("获取多个Set并集失败 keys: {}, error: {}", keys, e.getMessage());
            return Collections.emptySet();
        }
    }

    /**
     * 获取两个Set的交集
     */
    public Set<Object> setIntersect(String key1, String key2) {
        try {
            return redisTemplate.opsForSet().intersect(key1, key2);
        } catch (Exception e) {
            log.error("获取Set交集失败 key1: {}, key2: {}, error: {}", 
                    key1, key2, e.getMessage());
            return Collections.emptySet();
        }
    }

    /**
     * 获取两个Set的差集(key1中有但key2中没有的元素)
     */
    public Set<Object> setDifference(String key1, String key2) {
        try {
            return redisTemplate.opsForSet().difference(key1, key2);
        } catch (Exception e) {
            log.error("获取Set差集失败 key1: {}, key2: {}, error: {}", 
                    key1, key2, e.getMessage());
            return Collections.emptySet();
        }
    }

    /**
     * 将一个Set中的元素移动到另一个Set
     */
    public Boolean moveSetMember(String sourceKey, Object value, String destinationKey) {
        try {
            Boolean moved = redisTemplate.opsForSet().move(sourceKey, value, destinationKey);
            log.info("移动Set元素 sourceKey: {}, value: {}, destinationKey: {}, result: {}", 
                    sourceKey, value, destinationKey, moved);
            return moved;
        } catch (Exception e) {
            log.error("移动Set元素失败 sourceKey: {}, destinationKey: {}, error: {}", 
                    sourceKey, destinationKey, e.getMessage());
            return false;
        }
    }

    // ============================== ZSet 数据类型详细操作 ==============================
    
    /**
     * 向ZSet中添加多个元素
     */
    public Long addToZSet(String key, Map<Object, Double> valueScoreMap) {
        try {
            Set<ZSetOperations.TypedTuple<Object>> tuples = new HashSet<>();
            for (Map.Entry<Object, Double> entry : valueScoreMap.entrySet()) {
                tuples.add(new DefaultTypedTuple<>(entry.getKey(), entry.getValue()));
            }
            Long count = redisTemplate.opsForZSet().add(key, tuples);
            log.info("ZSet批量添加成功 key: {}, 添加数量: {}", key, count);
            return count;
        } catch (Exception e) {
            log.error("ZSet批量添加失败 key: {}, error: {}", key, e.getMessage());
            return 0L;
        }
    }

    /**
     * 增加ZSet中某个元素的分数
     */
    public Double incrementZSetScore(String key, Object value, double delta) {
        try {
            Double newScore = redisTemplate.opsForZSet().incrementScore(key, value, delta);
            log.info("ZSet增加分数成功 key: {}, value: {}, delta: {}, newScore: {}", 
                    key, value, delta, newScore);
            return newScore;
        } catch (Exception e) {
            log.error("ZSet增加分数失败 key: {}, value: {}, error: {}", 
                    key, value, e.getMessage());
            return null;
        }
    }

    /**
     * 减少ZSet中某个元素的分数
     */
    public Double decrementZSetScore(String key, Object value, double delta) {
        try {
            Double newScore = redisTemplate.opsForZSet().incrementScore(key, value, -delta);
            log.info("ZSet减少分数成功 key: {}, value: {}, delta: {}, newScore: {}", 
                    key, value, delta, newScore);
            return newScore;
        } catch (Exception e) {
            log.error("ZSet减少分数失败 key: {}, value: {}, error: {}", 
                    key, value, e.getMessage());
            return null;
        }
    }

    /**
     * 获取ZSet中指定排名范围的元素和分数
     */
    public Set<ZSetOperations.TypedTuple<Object>> getZSetRangeWithScores(String key, long start, long end) {
        try {
            return redisTemplate.opsForZSet().rangeWithScores(key, start, end);
        } catch (Exception e) {
            log.error("获取ZSet元素和分数失败 key: {}, start: {}, end: {}, error: {}", 
                    key, start, end, e.getMessage());
            return Collections.emptySet();
        }
    }

    /**
     * 获取ZSet中指定分数范围的元素和分数
     */
    public Set<ZSetOperations.TypedTuple<Object>> getZSetRangeByScoreWithScores(
            String key, double min, double max) {
        try {
            return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max);
        } catch (Exception e) {
            log.error("获取ZSet分数范围的元素和分数失败 key: {}, min: {}, max: {}, error: {}", 
                    key, min, max, e.getMessage());
            return Collections.emptySet();
        }
    }

    /**
     * 获取ZSet中指定分数范围的元素和分数(带分页)
     */
    public Set<ZSetOperations.TypedTuple<Object>> getZSetRangeByScoreWithScores(
            String key, double min, double max, long offset, long count) {
        try {
            return redisTemplate.opsForZSet().rangeByScoreWithScores(key, min, max, offset, count);
        } catch (Exception e) {
            log.error("获取ZSet分数范围的元素和分数(分页)失败 key: {}, min: {}, max: {}, offset: {}, count: {}, error: {}", 
                    key, min, max, offset, count, e.getMessage());
            return Collections.emptySet();
        }
    }

    /**
     * 获取ZSet中指定值的排名(降序)
     */
    public Long getZSetReverseRank(String key, Object value) {
        try {
            return redisTemplate.opsForZSet().reverseRank(key, value);
        } catch (Exception e) {
            log.error("获取ZSet反向排名失败 key: {}, value: {}, error: {}", 
                    key, value, e.getMessage());
            return null;
        }
    }

    /**
     * 获取ZSet中指定分数范围的元素数量
     */
    public Long getZSetCountByScore(String key, double min, double max) {
        try {
            return redisTemplate.opsForZSet().count(key, min, max);
        } catch (Exception e) {
            log.error("获取ZSet分数范围数量失败 key: {}, min: {}, max: {}, error: {}", 
                    key, min, max, e.getMessage());
            return 0L;
        }
    }

    /**
     * 移除ZSet中指定排名范围的元素
     */
    public Long removeZSetRangeByRank(String key, long start, long end) {
        try {
            Long count = redisTemplate.opsForZSet().removeRange(key, start, end);
            log.info("移除ZSet排名范围元素成功 key: {}, start: {}, end: {}, count: {}", 
                    key, start, end, count);
            return count;
        } catch (Exception e) {
            log.error("移除ZSet排名范围元素失败 key: {}, start: {}, end: {}, error: {}", 
                    key, start, end, e.getMessage());
            return 0L;
        }
    }

    /**
     * 移除ZSet中指定分数范围的元素
     */
    public Long removeZSetRangeByScore(String key, double min, double max) {
        try {
            Long count = redisTemplate.opsForZSet().removeRangeByScore(key, min, max);
            log.info("移除ZSet分数范围元素成功 key: {}, min: {}, max: {}, count: {}", 
                    key, min, max, count);
            return count;
        } catch (Exception e) {
            log.error("移除ZSet分数范围元素失败 key: {}, min: {}, max: {}, error: {}", 
                    key, min, max, e.getMessage());
            return 0L;
        }
    }

    /**
     * 获取ZSet中最小分数
     */
    public Double getZSetMinScore(String key) {
        try {
            Set<ZSetOperations.TypedTuple<Object>> set = redisTemplate.opsForZSet()
                    .rangeWithScores(key, 0, 0);
            if (set != null && !set.isEmpty()) {
                return set.iterator().next().getScore();
            }
            return null;
        } catch (Exception e) {
            log.error("获取ZSet最小分数失败 key: {}, error: {}", key, e.getMessage());
            return null;
        }
    }

    /**
     * 获取ZSet中最大分数
     */
    public Double getZSetMaxScore(String key) {
        try {
            Set<ZSetOperations.TypedTuple<Object>> set = redisTemplate.opsForZSet()
                    .reverseRangeWithScores(key, 0, 0);
            if (set != null && !set.isEmpty()) {
                return set.iterator().next().getScore();
            }
            return null;
        } catch (Exception e) {
            log.error("获取ZSet最大分数失败 key: {}, error: {}", key, e.getMessage());
            return null;
        }
    }

    // ============================== Hash(Map) 数据类型详细操作 ==============================
    
    /**
     * 批量设置Hash值(如果字段不存在则设置)
     */
    public void setHashIfAbsent(String key, Map<String, Object> map) {
        try {
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                redisTemplate.opsForHash().putIfAbsent(key, entry.getKey(), entry.getValue());
            }
            log.info("Hash批量设置(不存在才设置)成功 key: {}, map: {}", key, map);
        } catch (Exception e) {
            log.error("Hash批量设置(不存在才设置)失败 key: {}, error: {}", key, e.getMessage());
        }
    }

    /**
     * 增加Hash中某个字段的数值(整型)
     */
    public Long incrementHash(String key, String hashKey, long delta) {
        try {
            Long newValue = redisTemplate.opsForHash().increment(key, hashKey, delta);
            log.info("Hash字段增加成功 key: {}, hashKey: {}, delta: {}, newValue: {}", 
                    key, hashKey, delta, newValue);
            return newValue;
        } catch (Exception e) {
            log.error("Hash字段增加失败 key: {}, hashKey: {}, error: {}", 
                    key, hashKey, e.getMessage());
            return null;
        }
    }

    /**
     * 增加Hash中某个字段的数值(浮点型)
     */
    public Double incrementHash(String key, String hashKey, double delta) {
        try {
            Double newValue = redisTemplate.opsForHash().increment(key, hashKey, delta);
            log.info("Hash字段增加(浮点)成功 key: {}, hashKey: {}, delta: {}, newValue: {}", 
                    key, hashKey, delta, newValue);
            return newValue;
        } catch (Exception e) {
            log.error("Hash字段增加(浮点)失败 key: {}, hashKey: {}, error: {}", 
                    key, hashKey, e.getMessage());
            return null;
        }
    }

    /**
     * 获取Hash中多个字段的值
     */
    public List<Object> getMultiHash(String key, List<String> hashKeys) {
        try {
            return redisTemplate.opsForHash().multiGet(key, Arrays.asList(hashKeys.toArray()));
        } catch (Exception e) {
            log.error("获取Hash多个字段失败 key: {}, hashKeys: {}, error: {}", 
                    key, hashKeys, e.getMessage());
            return Collections.emptyList();
        }
    }

    /**
     * 获取Hash的长度(字段数量)
     */
    public Long getHashLength(String key) {
        try {
            return redisTemplate.opsForHash().size(key);
        } catch (Exception e) {
            log.error("获取Hash长度失败 key: {}, error: {}", key, e.getMessage());
            return 0L;
        }
    }

    /**
     * 批量删除Hash中的字段
     */
    public Long deleteHashFields(String key, List<String> hashKeys) {
        try {
            return redisTemplate.opsForHash().delete(key, hashKeys.toArray());
        } catch (Exception e) {
            log.error("批量删除Hash字段失败 key: {}, hashKeys: {}, error: {}", 
                    key, hashKeys, e.getMessage());
            return 0L;
        }
    }

    /**
     * 获取Hash中的所有字段和值
     */
    public Map<String, Object> getHashAllAsString(String key) {
        try {
            Map<Object, Object> entries = redisTemplate.opsForHash().entries(key);
            Map<String, Object> result = new HashMap<>();
            for (Map.Entry<Object, Object> entry : entries.entrySet()) {
                result.put(entry.getKey().toString(), entry.getValue());
            }
            return result;
        } catch (Exception e) {
            log.error("获取Hash所有字段和值失败 key: {}, error: {}", key, e.getMessage());
            return Collections.emptyMap();
        }
    }

    /**
     * 扫描Hash中的字段(用于大数据量)
     */
    public Map<String, Object> scanHash(String key, String pattern, int count) {
        try {
            Map<String, Object> result = new HashMap<>();
            Cursor<Map.Entry<Object, Object>> cursor = redisTemplate.opsForHash()
                    .scan(key, ScanOptions.scanOptions().match(pattern).count(count).build());
            
            while (cursor.hasNext()) {
                Map.Entry<Object, Object> entry = cursor.next();
                result.put(entry.getKey().toString(), entry.getValue());
            }
            cursor.close();
            return result;
        } catch (Exception e) {
            log.error("扫描Hash失败 key: {}, pattern: {}, error: {}", key, pattern, e.getMessage());
            return Collections.emptyMap();
        }
    }

5.控制器类中的实际调用示例

复制代码
package com.example.redis.controller;

import com.example.redis.service.RedisDataService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.web.bind.annotation.*;

import java.util.*;

@Slf4j
@RestController
@RequestMapping("/redis/data")
public class RedisDataController {

    @Autowired
    private RedisDataService redisDataService;

    // ============================== Set 操作示例 ==============================
    
    /**
     * 示例1:用户标签系统
     */
    @PostMapping("/set/userTags")
    public Map<String, Object> setUserTags() {
        Map<String, Object> result = new HashMap<>();
        
        // 用户1的标签
        redisDataService.addToSetWithExpire("user:tags:1001", 86400, 
                "VIP", "活跃用户", "北京", "程序员", "技术爱好者");
        
        // 用户2的标签
        redisDataService.addToSetWithExpire("user:tags:1002", 86400,
                "新用户", "上海", "设计师", "艺术爱好者");
        
        // 用户3的标签
        redisDataService.addToSetWithExpire("user:tags:1003", 86400,
                "VIP", "广州", "产品经理", "技术爱好者");
        
        // 获取共同标签
        Set<Object> commonTags = redisDataService.setIntersect("user:tags:1001", "user:tags:1003");
        result.put("用户1和用户3的共同标签", commonTags);
        
        // 获取所有标签
        Set<Object> allTags = redisDataService.setUnion(
                Arrays.asList("user:tags:1001", "user:tags:1002", "user:tags:1003"));
        result.put("所有用户的标签", allTags);
        
        // 随机推荐标签
        Object randomTag = redisDataService.getRandomSetMember("user:tags:1001");
        result.put("为用户1随机推荐的标签", randomTag);
        
        return result;
    }

    /**
     * 示例2:抽奖系统
     */
    @PostMapping("/set/lottery")
    public Map<String, Object> lotterySystem() {
        Map<String, Object> result = new HashMap<>();
        
        // 添加抽奖参与者
        String[] participants = {
                "张三", "李四", "王五", "赵六", "钱七",
                "孙八", "周九", "吴十", "郑十一", "王十二"
        };
        
        redisDataService.addToSetWithExpire("lottery:2023:participants", 3600, (Object[]) participants);
        
        // 随机抽取3名获奖者(不重复)
        List<Object> winners = redisDataService.popRandomSetMembers("lottery:2023:participants", 3);
        result.put("获奖者", winners);
        
        // 查看剩余参与者
        Set<Object> remaining = redisDataService.getAllSetMembers("lottery:2023:participants");
        result.put("剩余参与者", remaining);
        
        return result;
    }

    /**
     * 示例3:共同关注/好友系统
     */
    @PostMapping("/set/social")
    public Map<String, Object> socialSystem() {
        Map<String, Object> result = new HashMap<>();
        
        // 用户A的关注列表
        redisDataService.addToSet("user:follow:1001", "user:1002", "user:1003", "user:1004", "user:1005");
        
        // 用户B的关注列表
        redisDataService.addToSet("user:follow:1002", "user:1001", "user:1003", "user:1006", "user:1007");
        
        // 用户C的关注列表
        redisDataService.addToSet("user:follow:1003", "user:1001", "user:1002", "user:1004", "user:1008");
        
        // 共同关注
        Set<Object> commonFollow = redisDataService.setIntersect("user:follow:1001", "user:follow:1002");
        result.put("用户A和用户B的共同关注", commonFollow);
        
        // 可能认识的人(B关注了但A没关注的)
        Set<Object> recommendFollow = redisDataService.setDifference("user:follow:1002", "user:follow:1001");
        result.put("推荐给用户A关注的人", recommendFollow);
        
        // 相互关注(A关注B且B关注A)
        boolean isMutual = redisDataService.isSetMember("user:follow:1001", "user:1002") &&
                redisDataService.isSetMember("user:follow:1002", "user:1001");
        result.put("用户A和用户B是否相互关注", isMutual);
        
        return result;
    }

    // ============================== ZSet 操作示例 ==============================
    
    /**
     * 示例1:游戏排行榜
     */
    @PostMapping("/zset/gameRank")
    public Map<String, Object> gameRankingSystem() {
        Map<String, Object> result = new HashMap<>();
        
        // 初始化玩家分数
        Map<Object, Double> playerScores = new HashMap<>();
        playerScores.put("player:1001", 1500.0);
        playerScores.put("player:1002", 2300.0);
        playerScores.put("player:1003", 1800.0);
        playerScores.put("player:1004", 1950.0);
        playerScores.put("player:1005", 2100.0);
        
        redisDataService.addToZSet("game:rank:league1", playerScores);
        
        // 更新分数(玩家赢得比赛)
        Double newScore = redisDataService.incrementZSetScore("game:rank:league1", "player:1001", 50.5);
        result.put("玩家1001新分数", newScore);
        
        // 获取前三名
        Set<ZSetOperations.TypedTuple<Object>> top3 = redisDataService
                .getZSetRangeWithScores("game:rank:league1", 0, 2);
        result.put("排行榜前三名", formatZSetResult(top3));
        
        // 获取玩家排名
        Long rank = redisDataService.getZSetReverseRank("game:rank:league1", "player:1001");
        result.put("玩家1001的排名", rank != null ? rank + 1 : "未上榜");
        
        // 获取分数段玩家(1800-2200分)
        Set<ZSetOperations.TypedTuple<Object>> midRange = redisDataService
                .getZSetRangeByScoreWithScores("game:rank:league1", 1800, 2200);
        result.put("1800-2200分段的玩家", formatZSetResult(midRange));
        
        return result;
    }

    /**
     * 示例2:热门商品排行榜
     */
    @PostMapping("/zset/productHotRank")
    public Map<String, Object> productHotRanking() {
        Map<String, Object> result = new HashMap<>();
        
        // 模拟商品热度数据(热度 = 点击量 * 0.3 + 销量 * 0.7)
        Map<Object, Double> productHeat = new HashMap<>();
        productHeat.put("product:1001", 850.5);  // 热度值
        productHeat.put("product:1002", 1200.3);
        productHeat.put("product:1003", 750.2);
        productHeat.put("product:1004", 980.7);
        productHeat.put("product:1005", 650.1);
        productHeat.put("product:1006", 1100.8);
        
        redisDataService.addToZSet("product:heat:rank", productHeat);
        
        // 商品1001增加热度(用户点击)
        redisDataService.incrementZSetScore("product:heat:rank", "product:1001", 15.5);
        
        // 商品1002减少热度(热度衰减)
        redisDataService.decrementZSetScore("product:heat:rank", "product:1002", 20.0);
        
        // 获取热门商品Top5
        Set<ZSetOperations.TypedTuple<Object>> top5 = redisDataService
                .getZSetReverseRangeWithScores("product:heat:rank", 0, 4);
        result.put("热门商品Top5", formatZSetResult(top5));
        
        // 获取热度范围
        Double minHeat = redisDataService.getZSetMinScore("product:heat:rank");
        Double maxHeat = redisDataService.getZSetMaxScore("product:heat:rank");
        result.put("最低热度", minHeat);
        result.put("最高热度", maxHeat);
        
        // 分页获取商品(第2页,每页2个)
        Set<ZSetOperations.TypedTuple<Object>> page2 = redisDataService
                .getZSetRangeByScoreWithScores("product:heat:rank", 0, Double.MAX_VALUE, 2, 2);
        result.put("第二页商品", formatZSetResult(page2));
        
        return result;
    }

    /**
     * 示例3:延时任务队列
     */
    @PostMapping("/zset/delayQueue")
    public Map<String, Object> delayQueueExample() {
        Map<String, Object> result = new HashMap<>();
        
        long currentTime = System.currentTimeMillis();
        
        // 添加延时任务(score为执行时间戳)
        redisDataService.addToZSet("system:delay:queue", "task:order:1001", currentTime + 5000);  // 5秒后执行
        redisDataService.addToZSet("system:delay:queue", "task:order:1002", currentTime + 10000); // 10秒后执行
        redisDataService.addToZSet("system:delay:queue", "task:notify:1001", currentTime + 3000);  // 3秒后执行
        redisDataService.addToZSet("system:delay:queue", "task:clean:cache", currentTime + 60000); // 60秒后执行
        
        // 模拟检查到期任务
        Set<ZSetOperations.TypedTuple<Object>> dueTasks = redisDataService
                .getZSetRangeByScoreWithScores("system:delay:queue", 0, currentTime + 6000);
        
        result.put("6秒内到期的任务", formatZSetResult(dueTasks));
        
        // 移除已处理的任务
        if (!dueTasks.isEmpty()) {
            List<Object> tasksToRemove = new ArrayList<>();
            for (ZSetOperations.TypedTuple<Object> tuple : dueTasks) {
                tasksToRemove.add(tuple.getValue());
            }
            redisDataService.removeFromZSet("system:delay:queue", tasksToRemove.toArray());
            result.put("已移除的任务", tasksToRemove);
        }
        
        return result;
    }

    // ============================== Hash(Map) 操作示例 ==============================
    
    /**
     * 示例1:用户会话管理
     */
    @PostMapping("/hash/userSession")
    public Map<String, Object> userSessionManagement() {
        Map<String, Object> result = new HashMap<>();
        
        // 用户1的会话信息
        Map<String, Object> session1 = new HashMap<>();
        session1.put("userId", "1001");
        session1.put("username", "张三");
        session1.put("loginTime", System.currentTimeMillis());
        session1.put("lastActivity", System.currentTimeMillis());
        session1.put("ip", "192.168.1.100");
        session1.put("userAgent", "Mozilla/5.0");
        session1.put("token", "abc123xyz");
        
        redisDataService.setHashAll("session:user:1001", session1);
        
        // 更新最后活动时间
        redisDataService.incrementHash("session:user:1001", "lastActivity", System.currentTimeMillis());
        
        // 获取会话信息
        Map<String, Object> sessionInfo = redisDataService.getHashAllAsString("session:user:1001");
        result.put("用户会话信息", sessionInfo);
        
        // 获取多个字段
        List<String> fields = Arrays.asList("username", "loginTime", "ip");
        List<Object> fieldValues = redisDataService.getMultiHash("session:user:1001", fields);
        result.put("指定字段值", fieldValues);
        
        // 扫描会话(查找特定模式的会话)
        Map<String, Object> scannedSessions = redisDataService.scanHash("session:user:1001", "*Time*", 10);
        result.put("扫描到的Time相关字段", scannedSessions);
        
        return result;
    }

    /**
     * 示例2:商品库存管理
     */
    @PostMapping("/hash/productInventory")
    public Map<String, Object> productInventorySystem() {
        Map<String, Object> result = new HashMap<>();
        
        // 初始化商品库存
        Map<String, Object> inventory = new HashMap<>();
        inventory.put("product:1001:stock", 150);
        inventory.put("product:1001:price", 299.99);
        inventory.put("product:1001:name", "iPhone 14");
        inventory.put("product:1001:color", "黑色");
        
        inventory.put("product:1002:stock", 80);
        inventory.put("product:1002:price", 899.99);
        inventory.put("product:1002:name", "MacBook Pro");
        inventory.put("product:1002:color", "银色");
        
        redisDataService.setHashAll("inventory:products", inventory);
        
        // 扣减库存(原子操作)
        Long remainingStock = redisDataService.incrementHash("inventory:products", "product:1001:stock", -5);
        result.put("商品1001扣减5个库存后剩余", remainingStock);
        
        // 增加库存
        Long newStock = redisDataService.incrementHash("inventory:products", "product:1002:stock", 20);
        result.put("商品1002增加20个库存后总数", newStock);
        
        // 获取商品1001的所有信息
        Map<String, Object> product1001 = new HashMap<>();
        product1001.put("stock", redisDataService.getHash("inventory:products", "product:1001:stock"));
        product1001.put("price", redisDataService.getHash("inventory:products", "product:1001:price"));
        product1001.put("name", redisDataService.getHash("inventory:products", "product:1001:name"));
        
        result.put("商品1001详情", product1001);
        
        // 获取Hash大小
        Long hashSize = redisDataService.getHashLength("inventory:products");
        result.put("库存Hash中的字段数量", hashSize);
        
        return result;
    }

    /**
     * 示例3:配置管理中心
     */
    @PostMapping("/hash/configCenter")
    public Map<String, Object> configCenterExample() {
        Map<String, Object> result = new HashMap<>();
        
        // 系统配置
        Map<String, Object> systemConfig = new HashMap<>();
        systemConfig.put("app.name", "电商平台");
        systemConfig.put("app.version", "2.0.1");
        systemConfig.put("api.timeout", "30000");
        systemConfig.put("cache.enabled", "true");
        systemConfig.put("cache.ttl", "3600");
        systemConfig.put("log.level", "INFO");
        systemConfig.put("max.connections", "100");
        systemConfig.put("feature.flag.newUI", "false");
        
        redisDataService.setHashAll("config:system", systemConfig);
        
        // 动态更新配置(如果不存在则设置)
        Map<String, Object> newConfigs = new HashMap<>();
        newConfigs.put("api.retry.count", "3");
        newConfigs.put("feature.flag.newUI", "true"); // 这个已存在,不会更新
        newConfigs.put("backup.enabled", "false");
        
        redisDataService.setHashIfAbsent("config:system", newConfigs);
        
        // 获取所有配置
        Map<String, Object> allConfigs = redisDataService.getHashAllAsString("config:system");
        result.put("所有系统配置", allConfigs);
        
        // 批量删除配置
        List<String> configsToRemove = Arrays.asList("feature.flag.newUI", "backup.enabled");
        Long deletedCount = redisDataService.deleteHashFields("config:system", configsToRemove);
        result.put("删除的配置数量", deletedCount);
        
        // 更新后的配置
        Map<String, Object> updatedConfigs = redisDataService.getHashAllAsString("config:system");
        result.put("更新后的配置", updatedConfigs);
        
        return result;
    }

    /**
     * 示例4:购物车实现
     */
    @PostMapping("/hash/shoppingCart")
    public Map<String, Object> shoppingCartImplementation() {
        Map<String, Object> result = new HashMap<>();
        
        // 用户1001的购物车
        Map<String, Object> cartItems = new HashMap<>();
        cartItems.put("product:1001", "2"); // 商品ID: 数量
        cartItems.put("product:1002", "1");
        cartItems.put("product:1003", "3");
        
        redisDataService.setHashAll("cart:user:1001", cartItems);
        
        // 添加商品到购物车
        Long newQuantity = redisDataService.incrementHash("cart:user:1001", "product:1001", 1);
        result.put("商品1001增加1个后数量", newQuantity);
        
        // 减少商品数量
        Long updatedQuantity = redisDataService.incrementHash("cart:user:1001", "product:1003", -1);
        result.put("商品1003减少1个后数量", updatedQuantity);
        
        // 获取购物车所有商品
        Map<String, Object> cart = redisDataService.getHashAllAsString("cart:user:1001");
        result.put("购物车内容", cart);
        
        // 获取购物车商品总数
        Long totalItems = 0L;
        for (Object quantity : cart.values()) {
            totalItems += Long.parseLong(quantity.toString());
        }
        result.put("购物车商品总数", totalItems);
        
        // 清空部分商品
        List<String> itemsToRemove = Arrays.asList("product:1002");
        redisDataService.deleteHashFields("cart:user:1001", itemsToRemove);
        
        // 清空后的购物车
        Map<String, Object> clearedCart = redisDataService.getHashAllAsString("cart:user:1001");
        result.put("清空部分商品后的购物车", clearedCart);
        
        return result;
    }

    // ============================== 工具方法 ==============================
    
    /**
     * 格式化ZSet结果
     */
    private List<Map<String, Object>> formatZSetResult(Set<ZSetOperations.TypedTuple<Object>> tuples) {
        List<Map<String, Object>> result = new ArrayList<>();
        for (ZSetOperations.TypedTuple<Object> tuple : tuples) {
            Map<String, Object> item = new HashMap<>();
            item.put("value", tuple.getValue());
            item.put("score", tuple.getScore());
            result.add(item);
        }
        return result;
    }

    /**
     * 获取ZSet反向排名范围(带分数)
     */
    private Set<ZSetOperations.TypedTuple<Object>> getZSetReverseRangeWithScores(String key, long start, long end) {
        try {
            return redisTemplate.opsForZSet().reverseRangeWithScores(key, start, end);
        } catch (Exception e) {
            log.error("获取ZSet反向范围带分数失败 key: {}, start: {}, end: {}, error: {}", 
                    key, start, end, e.getMessage());
            return Collections.emptySet();
        }
    }
}

6.测试工具类

复制代码
package com.example.redis.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Set;

@Component
public class RedisDataTypeDemo {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 演示所有Redis数据类型的操作
     */
    public void demoAllDataTypes() {
        System.out.println("========== Redis 数据类型操作演示 ==========");
        
        // 1. String 类型演示
        demoStringType();
        
        // 2. List 类型演示
        demoListType();
        
        // 3. Hash (Map) 类型演示
        demoHashType();
        
        // 4. Set 类型演示
        demoSetType();
        
        // 5. ZSet 类型演示
        demoZSetType();
        
        System.out.println("========== 演示结束 ==========");
    }

    private void demoStringType() {
        System.out.println("\n--- String 类型演示 ---");
        
        // 设置字符串
        redisTemplate.opsForValue().set("demo:string:key1", "Hello Redis");
        redisTemplate.opsForValue().set("demo:string:counter", "100");
        
        // 获取字符串
        String value = (String) redisTemplate.opsForValue().get("demo:string:key1");
        System.out.println("String值: " + value);
        
        // 递增操作
        Long newValue = redisTemplate.opsForValue().increment("demo:string:counter", 50);
        System.out.println("递增后: " + newValue);
        
        // 设置过期时间
        redisTemplate.opsForValue().set("demo:string:temp", "临时数据", 60);
    }

    private void demoListType() {
        System.out.println("\n--- List 类型演示 ---");
        
        // 从右侧插入
        redisTemplate.opsForList().rightPush("demo:list:messages", "消息1");
        redisTemplate.opsForList().rightPush("demo:list:messages", "消息2");
        redisTemplate.opsForList().rightPush("demo:list:messages", "消息3");
        
        // 从左侧插入
        redisTemplate.opsForList().leftPush("demo:list:messages", "紧急消息");
        
        // 获取列表范围
        System.out.println("所有消息: " + redisTemplate.opsForList().range("demo:list:messages", 0, -1));
        
        // 获取列表长度
        Long size = redisTemplate.opsForList().size("demo:list:messages");
        System.out.println("消息数量: " + size);
        
        // 获取指定索引的值
        Object firstMessage = redisTemplate.opsForList().index("demo:list:messages", 0);
        System.out.println("第一条消息: " + firstMessage);
    }

    private void demoHashType() {
        System.out.println("\n--- Hash (Map) 类型演示 ---");
        
        // 设置Hash值
        redisTemplate.opsForHash().put("demo:hash:user:1001", "name", "张三");
        redisTemplate.opsForHash().put("demo:hash:user:1001", "age", "25");
        redisTemplate.opsForHash().put("demo:hash:user:1001", "email", "zhangsan@example.com");
        
        // 获取Hash值
        String name = (String) redisTemplate.opsForHash().get("demo:hash:user:1001", "name");
        System.out.println("用户名: " + name);
        
        // 获取所有字段
        System.out.println("所有字段: " + redisTemplate.opsForHash().entries("demo:hash:user:1001"));
        
        // 检查字段是否存在
        boolean hasEmail = redisTemplate.opsForHash().hasKey("demo:hash:user:1001", "email");
        System.out.println("是否有email字段: " + hasEmail);
        
        // 增加数值字段
        redisTemplate.opsForHash().increment("demo:hash:user:1001", "age", 1);
        System.out.println("增加年龄后: " + redisTemplate.opsForHash().get("demo:hash:user:1001", "age"));
    }

    private void demoSetType() {
        System.out.println("\n--- Set 类型演示 ---");
        
        // 添加元素
        redisTemplate.opsForSet().add("demo:set:tags", "Java", "Redis", "Spring", "MySQL");
        redisTemplate.opsForSet().add("demo:set:tags", "Redis", "NoSQL"); // 重复元素不会被添加
        
        // 获取所有元素
        Set<Object> tags = redisTemplate.opsForSet().members("demo:set:tags");
        System.out.println("所有标签: " + tags);
        
        // 随机获取元素
        Object randomTag = redisTemplate.opsForSet().randomMember("demo:set:tags");
        System.out.println("随机标签: " + randomTag);
        
        // 检查元素是否存在
        boolean hasJava = redisTemplate.opsForSet().isMember("demo:set:tags", "Java");
        System.out.println("是否包含Java: " + hasJava);
        
        // 集合大小
        Long size = redisTemplate.opsForSet().size("demo:set:tags");
        System.out.println("标签数量: " + size);
    }

    private void demoZSetType() {
        System.out.println("\n--- ZSet 类型演示 ---");
        
        // 添加带分数的元素
        redisTemplate.opsForZSet().add("demo:zset:scores", "玩家A", 85.5);
        redisTemplate.opsForZSet().add("demo:zset:scores", "玩家B", 92.0);
        redisTemplate.opsForZSet().add("demo:zset:scores", "玩家C", 78.5);
        redisTemplate.opsForZSet().add("demo:zset:scores", "玩家D", 95.0);
        
        // 按分数升序获取
        System.out.println("升序排名: " + redisTemplate.opsForZSet().range("demo:zset:scores", 0, -1));
        
        // 按分数降序获取
        System.out.println("降序排名: " + redisTemplate.opsForZSet().reverseRange("demo:zset:scores", 0, -1));
        
        // 获取分数
        Double score = redisTemplate.opsForZSet().score("demo:zset:scores", "玩家B");
        System.out.println("玩家B的分数: " + score);
        
        // 获取排名(从0开始)
        Long rank = redisTemplate.opsForZSet().rank("demo:zset:scores", "玩家B");
        System.out.println("玩家B的排名: " + (rank != null ? rank + 1 : "未上榜"));
        
        // 增加分数
        Double newScore = redisTemplate.opsForZSet().incrementScore("demo:zset:scores", "玩家C", 10.0);
        System.out.println("玩家C增加分数后: " + newScore);
    }
}

7.启动类中的演示代码

复制代码
package com.example.redis;

import com.example.redis.util.RedisDataTypeDemo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class RedisDemoApplication implements CommandLineRunner {

    @Autowired
    private RedisDataTypeDemo redisDataTypeDemo;

    public static void main(String[] args) {
        SpringApplication.run(RedisDemoApplication.class, args);
        System.out.println("Redis 数据类型演示应用启动成功!");
        System.out.println("访问以下地址进行测试:");
        System.out.println("1. Set操作示例: http://localhost:8080/redis/data/set/userTags");
        System.out.println("2. ZSet操作示例: http://localhost:8080/redis/data/zset/gameRank");
        System.out.println("3. Hash操作示例: http://localhost:8080/redis/data/hash/userSession");
    }

    @Override
    public void run(String... args) throws Exception {
        // 启动时演示所有数据类型
        redisDataTypeDemo.demoAllDataTypes();
    }
}

8.使用示例说明

1. Set 类型实际应用场景

用户标签系统:

bash

复制代码
POST http://localhost:8080/redis/data/set/userTags
  • 存储用户标签

  • 查找共同标签

  • 标签推荐

抽奖系统:

bash

复制代码
POST http://localhost:8080/redis/data/set/lottery
  • 添加参与者

  • 随机抽取获奖者

  • 移除已抽中者

2. ZSet 类型实际应用场景

游戏排行榜:

bash

复制代码
POST http://localhost:8080/redis/data/zset/gameRank
  • 存储玩家分数

  • 实时更新分数

  • 获取排行榜

延时任务队列:

bash

复制代码
POST http://localhost:8080/redis/data/zset/delayQueue
  • 按执行时间排序

  • 定时检查到期任务

  • 原子性移除任务

3. Hash 类型实际应用场景

用户会话管理:

bash

POST http://localhost:8080/redis/data/hash/userSession

  • 存储用户会话信息

  • 原子更新字段

  • 批量获取字段

购物车实现:

bash

POST http://localhost:8080/redis/data/hash/shoppingCart

  • 商品ID作为field

  • 数量作为value

  • 原子增减数量

这些示例覆盖了Redis所有主要数据类型的实际应用场景,展示了如何在Spring Boot中操作这些数据类型。每个示例都包含了完整的业务逻辑和实际使用场景。

相关推荐
荒诞硬汉2 小时前
JavaBean相关补充
java·开发语言
提笔忘字的帝国2 小时前
【教程】macOS 如何完全卸载 Java 开发环境
java·开发语言·macos
2501_941882482 小时前
从灰度发布到流量切分的互联网工程语法控制与多语言实现实践思路随笔分享
java·开发语言
華勳全栈2 小时前
两天开发完成智能体平台
java·spring·go
alonewolf_993 小时前
Spring MVC重点功能底层源码深度解析
java·spring·mvc
沛沛老爹3 小时前
Java泛型擦除:原理、实践与应对策略
java·开发语言·人工智能·企业开发·发展趋势·技术原理
专注_每天进步一点点3 小时前
【java开发】写接口文档的札记
java·开发语言
代码方舟3 小时前
Java企业级实战:对接天远名下车辆数量查询API构建自动化风控中台
java·大数据·开发语言·自动化
AC赳赳老秦3 小时前
Python 爬虫进阶:DeepSeek 优化反爬策略与动态数据解析逻辑
开发语言·hadoop·spring boot·爬虫·python·postgresql·deepseek
zgl_200537793 小时前
ZGLanguage 解析SQL数据血缘 之 标识提取SQL语句中的目标表
java·大数据·数据库·数据仓库·hadoop·sql·源代码管理