《从零开始的java从入门到入土的学习生活——Java后端篇》Chapter21——Java后端篇学习记录——Redis初步入门

一、Redis是什么

Redis(Remote Dictionary Server)是一个基于内存 的键值存储数据库,通常放在应用和 MySQL 之间做缓存,用来扛住读流量,减轻 DB 压力。

基于内存:数据存在内存里,不经过磁盘 I/O,非常快,但是重启后数据会丢,所以 Redis 提供了 RDB 和 AOF 两种持久化机制来兜底。

键值储存:本质上就是一个巨大的 Map。但 Value 不限于字符串,Redis 内置了 5 种核心数据结构:

对比MYSQL数据:

二、Redis快速入门

1、前置准备

①引入依赖

XML 复制代码
<dependency>
<groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>

②连接配置

XML 复制代码
spring:
  redis:
    host: ${sky.redis.host}    #你的host
    port: ${sky.redis.port}    #你的port
    password: ${sky.redis.password}    #你的密码
    database: ${sky.redis.database}    #你的数据库数量

③在启动类启用缓存

java 复制代码
@SpringBootApplication
@EnableCaching
public class SkyApplication {
public static void main(String[] args) {
SpringApplication.run(SkyApplication.class, args);
}
}

2、手动Redis Template方式

①使用方法

②配置RedisTemplate

java 复制代码
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        log.info("开始创建redis模板对象...");
        RedisTemplate redisTemplate = new RedisTemplate();
        redisTemplate.setConnectionFactory(redisConnectionFactory);//设置连接工厂,连接redis服务器
        redisTemplate.setKeySerializer(new StringRedisSerializer());//设置key序列化器,将key转成普通字符串,keys * 可读
        return redisTemplate;
    }

**建议:**生产环境最好也给 value 配上 GenericJackson2JsonRedisSerializer ,方便排查。

③五大数据结构操作

java 复制代码
// ===== String(本项目最常用)=====
redisTemplate.opsForValue().set("key", value);
redisTemplate.opsForValue().set("key", value, 30, TimeUnit.MINUTES); // 带 TTL
redisTemplate.opsForValue().get("key");

// ===== Hash(适合存对象的多个属性)=====
redisTemplate.opsForHash().put("user:1001", "name", "张三");
redisTemplate.opsForHash().put("user:1001", "age", "25");
redisTemplate.opsForHash().get("user:1001", "name");

// ===== List(队列/消息栈)=====
redisTemplate.opsForList().leftPush("queue", item);
redisTemplate.opsForList().rightPop("queue");

// ===== Set(去重/标签/交集并集)=====
redisTemplate.opsForSet().add("tags:article1", "java", "redis");
redisTemplate.opsForSet().intersect("tags:article1", "tags:article2");

// ===== ZSet(排行榜/带权重的集合)=====
redisTemplate.opsForZSet().add("ranking", "user1", 95.5);
redisTemplate.opsForZSet().reverseRange("ranking", 0, 9); // Top 10

// ===== 通用操作 =====
redisTemplate.hasKey("key");//判断键是否存在
redisTemplate.expire("key", 30, TimeUnit.MINUTES);//设置过期时间
redisTemplate.delete("key");//删除

当手动操作多了之后,通常会封装一个工具类:

java 复制代码
@Component
public class RedisUtil {
@Autowired
private RedisTemplate redisTemplate;
// ===== String 操作 =====
public void set(String key, Object value) {
    redisTemplate.opsForValue().set(key, value);
}
public void set(String key, Object value, long timeout, TimeUnit unit) {
     redisTemplate.opsForValue().set(key, value, timeout, unit);
}
@SuppressWarnings("unchecked")
public <T> T get(String key) {
    return (T) redisTemplate.opsForValue().get(key);
}
// ===== 通用操作 =====
public boolean hasKey(String key) {
    return Boolean.TRUE.equals(redisTemplate.hasKey(key));
}
public void delete(String... keys) {
    redisTemplate.delete(Arrays.asList(keys));
}
public Set<String> keys(String pattern) {
    return redisTemplate.keys(pattern);
}
}

3、Spring Cache注解方式

①使用方法:

②自定义RedisCacheManager

Spring Boot 自动装配的默认 CacheManager 是裸的------没有过期时间,值是 Java 二进制序列化。生产环境一般都要自定义:

java 复制代码
 /**
     * 自定义缓存管理器,为 @Cacheable/@CacheEvict 注解提供统一的缓存策略
     * <p>
     * 默认规则:Key 用字符串序列化、Value 用 JSON 序列化、30 分钟过期、不缓存 null
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        // Value 序列化器:将 Java 对象转成 JSON 字符串存入 Redis,redis-cli 可读
        GenericJackson2JsonRedisSerializer jsonSerializer =
                new GenericJackson2JsonRedisSerializer();
        // Key 序列化器:将 Key 转成普通字符串,keys * 可读
        StringRedisSerializer stringSerializer = new StringRedisSerializer();

        // 基于默认配置模板,逐步定制缓存行为
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                // 缓存过期时间:30 分钟后自动删除,防止 Redis 内存无限增长
                .entryTtl(Duration.ofMinutes(30))
                // Key 的序列化方式:StringRedisSerializer → "setmealCache::1"
                .serializeKeysWith(RedisSerializationContext.SerializationPair
                        .fromSerializer(stringSerializer))
                // Value 的序列化方式:GenericJackson2JsonRedisSerializer → [{"id":1,...}]
                .serializeValuesWith(RedisSerializationContext.SerializationPair
                        .fromSerializer(jsonSerializer))
                // 方法返回 null 时不缓存,防止缓存穿透
                .disableCachingNullValues();

        // 构建 RedisCacheManager,将上述配置作为所有 cacheNames 的默认规则
        return RedisCacheManager.builder(factory)
                .cacheDefaults(config)
                .build();
    }

③常见的三种缓存注解:

|-------------|-----------------|------------|-----------|---------------------|
| 注解 | 作用 | 执行方法体? | 更新缓存? | 使用场景 |
| @Cacheable | 先查缓存,没有则执行方法并缓存 | 缓存命中时不执行 | 是(首次) | GET / 查询 |
| @CacheEvict | 删除缓存 | 始终执行 | 否 | POST / PUT / DELETE |
| @CachePut | 始终执行方法,结果更新到缓存 | 始终执行 | 是(每次) | 极少用 |

java 复制代码
//常用属性
@Cacheable(
cacheNames = "userCache", // 缓存名字空间(必填)
key = "#userId", // 缓存 key,SpEL 表达式
keyGenerator = "myKeyGenerator", // 自定义 key 生成策略
condition = "#userId > 100", // 条件满足才缓存
unless = "#result == null" // 结果为 null 时不缓存
)
@Cacheable ------ 查询缓存
java 复制代码
@GetMapping("/list")
@Cacheable(cacheNames = "setmealCache", key = "#categoryId")
    public Result<List<SetmealVO>> list(Long categoryId) {
        List<SetmealVO> list = setmealService.list(categoryId);
        return Result.success(list);
}

执行流程:

@CacheEvict ------ 缓存失效

新增一个分类 3 的套餐 → 只删 setmealCache::3 → 其他分类缓存不受影响。

java 复制代码
//精准删除(新增时)
@PostMapping
@CacheEvict(cacheNames = "setmealCache", key = "#setMealDTO.categoryId")
public Result save(@RequestBody SetMealDTO setMealDTO) {
    setmealService.saveWithDish(setMealDTO);
    return Result.success();
}
java 复制代码
//全量删除(修改/删除时)
@PutMapping
@CacheEvict(cacheNames = "setmealCache", allEntries = true)
public Result update(@RequestBody SetMealDTO setMealDTO) {
    setmealService.update(setMealDTO);
    return Result.success();
}

4、两种方式对比

相关推荐
吃好睡好便好1 小时前
在Matlab中绘制马鞍函数曲面图
开发语言·人工智能·学习·算法·matlab·信息可视化
ID_180079054731 小时前
淘宝店铺所有商品 API 接口:核心能力与数据返回参考
java·服务器·前端
医工交叉实验工坊1 小时前
Dot blot 实验注意事项
学习
Lucky_ldy1 小时前
C语言学习:内存函数
学习
轻刀快马1 小时前
浅聊Java反射
java·开发语言
Gerardisite1 小时前
企业微信智能客服开发实战:API自动回复指南
java·开发语言·python·机器人·企业微信
NNYSJYKJ1 小时前
K12 学习常见问题破解:脑能思维链的算法与教育应用
学习·算法
要开心吖ZSH1 小时前
零基础入门 Spring WebFlux 与 Project Reactor:从小白到顿悟
java·响应式编程·spring webflux
智塑未来1 小时前
装备制造行业设计制造一体化痛点攻克与实战经验总结
java·开发语言·制造