当前位置: 首页 > news >正文

java每日精进 5.25【Redis缓存】

1.Redis 缓存实现

1.1 编程式缓存(Spring Data Redis)

编程式缓存使用 Spring Data Redis 框架,通过 RedisTemplate 操作 Redis,结合 Redisson 客户端实现。本例以缓存 OAuth2 访问令牌(OAuth2AccessTokenDO)为例。

步骤 1:添加依赖

项目引入了 Redisson 的 Spring Boot Starter 依赖,以支持 Redis 操作。

<dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId>
</dependency>
  • 解释:Redisson 是一个功能强大的 Redis 客户端,支持分布式锁、队列、限流等功能。引入此依赖后,Spring Boot 可以通过 Redisson 连接 Redis,并使用 RedisTemplate 进行编程式缓存操作。
步骤 2:配置 Redis 连接

在 application-local.yaml 文件中,通过 spring.redis 配置项设置 Redis 连接参数。

redis:host: 127.0.0.1 # Redis 服务器地址port: 6379      # Redis 端口database: 0     # Redis 数据库索引
# password: dev   # 密码(生产环境建议启用)
  • 解释:此配置指定了 Redis 服务器的地址、端口和数据库索引。yudao 项目指出 Redisson 的默认配置通常无需额外调优,适用于大多数场景。
步骤 3:配置 RedisTemplate(JSON 序列化)

在 YudaoRedisAutoConfiguration 类中,项目自定义了 RedisTemplate,使用 JSON 序列化存储复杂对象的值。

@AutoConfiguration(before = RedissonAutoConfiguration.class)
public class YudaoRedisAutoConfiguration {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {// 创建 RedisTemplateRedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);// 设置键序列化(String)template.setKeySerializer(RedisSerializer.string());template.setHashKeySerializer(RedisSerializer.string());// 设置值序列化(JSON)template.setValueSerializer(buildRedisSerializer());template.setHashValueSerializer(buildRedisSerializer());return template;}public static RedisSerializer<?> buildRedisSerializer() {RedisSerializer<Object> json = RedisSerializer.json();// 支持 LocalDateTime 序列化ObjectMapper objectMapper = (ObjectMapper) ReflectUtil.getFieldValue(json, "mapper");objectMapper.registerModules(new JavaTimeModule());return json;}
}

解释

  • 目的:定义一个 RedisTemplate bean,用于 Redis 的键值操作。
  • 序列化
    • :使用 StringRedisSerializer,确保键以字符串形式存储(如 oauth2_access_token:token123)。
    • :使用 Jackson2JsonRedisSerializer(通过 RedisSerializer.json()),将复杂对象(如 OAuth2AccessTokenDO)序列化为 JSON。
    • LocalDateTime 支持:通过注册 JavaTimeModule,确保 Jackson 可以正确序列化/反序列化 Java 8 的日期时间类型(如 LocalDateTime)。
  • 优先级:@AutoConfiguration(before = RedissonAutoConfiguration.class) 确保自定义 RedisTemplate 在 Redisson 默认配置之前加载,以覆盖默认设置。
步骤 4:定义数据对象(OAuth2AccessTokenDO)

项目定义了一个数据对象 OAuth2AccessTokenDO,用于表示存储在 Redis 中的访问令牌结构。

@TableName(value = "system_oauth2_access_token", autoResultMap = true)
@KeySequence("system_oauth2_access_token_seq")
@Data
@EqualsAndHashCode(callSuper = true)
public class OAuth2AccessTokenDO extends TenantBaseDO {@TableIdprivate Long id; // 主键private String accessToken; // 访问令牌private String refreshToken; // 刷新令牌private Long userId; // 用户编号private Integer userType; // 用户类型@TableField(typeHandler = JacksonTypeHandler.class)private Map<String, String> userInfo; // 用户信息private String clientId; // 客户端编号@TableField(typeHandler = JacksonTypeHandler.class)private List<String> scopes; // 授权范围private LocalDateTime expiresTime; // 过期时间
}

解释

  • 作用:OAuth2AccessTokenDO 是一个数据对象(DO),用于映射数据库表 system_oauth2_access_token 和 Redis 中的缓存数据。
  • 注解
    • @TableName:指定 MyBatis-Plus 映射的表名。
    • @KeySequence:支持 Oracle、PostgreSQL 等数据库的主键自增(MySQL 可忽略)。
    • @TableField(typeHandler = JacksonTypeHandler.class):对复杂字段(如 userInfo 和 scopes)使用 Jackson 序列化,存储为 JSON。
  • 字段:包含访问令牌、用户编号、过期时间等信息,适合缓存复杂对象。
步骤 5:定义 Redis Key 常量(RedisKeyConstants)

项目通过 RedisKeyConstants 类集中管理 Redis 键,避免键名散落在代码中。

public interface RedisKeyConstants {String OAUTH2_ACCESS_TOKEN = "oauth2_access_token:%s";// 其他键定义...
}

解释

  • 目的:统一管理 Redis 键的格式,类似数据库表的规范管理。
  • 键格式:OAUTH2_ACCESS_TOKEN 使用 %s 占位符,动态生成键(如 oauth2_access_token:token123)。
  • 优势:通过查看 RedisKeyConstants,可以快速了解模块使用的所有 Redis 键,便于维护和调试。
步骤 6:实现 Redis 数据访问对象(OAuth2AccessTokenRedisDAO)

OAuth2AccessTokenRedisDAO 类封装了对 OAuth2AccessTokenDO 的 Redis 缓存操作。

@Repository
public class OAuth2AccessTokenRedisDAO {@Resourceprivate StringRedisTemplate stringRedisTemplate;public OAuth2AccessTokenDO get(String accessToken) {String redisKey = formatKey(accessToken);return JsonUtils.parseObject(stringRedisTemplate.opsForValue().get(redisKey), OAuth2AccessTokenDO.class);}public void set(OAuth2AccessTokenDO accessTokenDO) {String redisKey = formatKey(accessTokenDO.getAccessToken());// 清理多余字段,避免缓存accessTokenDO.setUpdater(null).setUpdateTime(null).setCreateTime(null).setCreator(null).setDeleted(null);long time = LocalDateTimeUtil.between(LocalDateTime.now(), accessTokenDO.getExpiresTime(), ChronoUnit.SECONDS);if (time > 0) {stringRedisTemplate.opsForValue().set(redisKey, JsonUtils.toJsonString(accessTokenDO), time, TimeUnit.SECONDS);}}public void delete(String accessToken) {String redisKey = formatKey(accessToken);stringRedisTemplate.delete(redisKey);}public void deleteList(Collection<String> accessTokens) {List<String> redisKeys = CollectionUtils.convertList(accessTokens, OAuth2AccessTokenRedisDAO::formatKey);stringRedisTemplate.delete(redisKeys);}private static String formatKey(String accessToken) {return String.format(OAUTH2_ACCESS_TOKEN, accessToken);}
}

解释

  • 注入:@Resource private StringRedisTemplate stringRedisTemplate 注入 StringRedisTemplate,用于操作字符串类型的键值对(值仍为 JSON)。
  • 方法
    • get:从 Redis 获取指定访问令牌的 OAuth2AccessTokenDO,通过 JsonUtils.parseObject 反序列化 JSON 为对象。
    • set:将 OAuth2AccessTokenDO 序列化为 JSON 存储到 Redis,设置动态过期时间(基于 expiresTime)。清理多余字段(如 updater)以减少缓存体积。
    • delete 和 deleteList:删除单个或多个访问令牌的缓存。
  • 键生成:formatKey 使用 RedisKeyConstants.OAUTH2_ACCESS_TOKEN 格式化键名,确保一致性。
步骤 7:业务逻辑中使用 Redis 缓存

在 OAuth2TokenServiceImpl 中,通过注入 OAuth2AccessTokenRedisDAO,实现访问令牌的缓存操作。

@Service
public class OAuth2TokenServiceImpl {@Resourceprivate OAuth2AccessTokenRedisDAO accessTokenRedisDAO;// 示例方法:获取访问令牌public OAuth2AccessTokenDO getAccessToken(String accessToken) {// 先从 Redis 获取OAuth2AccessTokenDO tokenDO = accessTokenRedisDAO.get(accessToken);if (tokenDO != null) {return tokenDO;}// 如果 Redis 没有,从数据库查询tokenDO = accessTokenMapper.selectByAccessToken(accessToken);if (tokenDO != null) {// 存入 RedisaccessTokenRedisDAO.set(tokenDO);}return tokenDO;}
}

解释

  • 缓存优先:先尝试从 Redis 获取令牌,若存在则直接返回。
  • 数据库回查:若 Redis 缓存不存在,则从数据库查询,并将结果存入 Redis。
  • 封装性:OAuth2AccessTokenRedisDAO 屏蔽了底层的 Redis 操作,业务代码只需调用 DAO 方法,逻辑简洁。

1.2 声明式缓存(Spring Cache)

声明式缓存基于 Spring Cache 框架,使用注解(如 @Cacheable)简化缓存操作。本例以角色(RoleDO)缓存为例。

步骤 1:添加依赖

引入 Spring Cache 依赖以启用注解式缓存。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId>
</dependency>
  • 解释:此依赖启用 Spring Cache 功能,支持 @Cacheable、@CachePut 和 @CacheEvict 注解。
步骤 2:配置 Redis 作为缓存后端

在 application.yaml 中配置 Redis 连接(与编程式缓存相同),并在 YudaoCacheAutoConfiguration 类中配置 Spring Cache。

@AutoConfiguration
@EnableConfigurationProperties({CacheProperties.class, YudaoCacheProperties.class})
@EnableCaching
public class YudaoCacheAutoConfiguration {@Bean@Primarypublic RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();// 使用单冒号作为键前缀分隔符config = config.computePrefixWith(cacheName -> {String keyPrefix = cacheProperties.getRedis().getKeyPrefix();if (StringUtils.hasText(keyPrefix)) {keyPrefix = keyPrefix.endsWith(":") ? keyPrefix : keyPrefix + ":";return keyPrefix + cacheName + ":";}return cacheName + ":";});// 使用 JSON 序列化config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(YudaoRedisAutoConfiguration.buildRedisSerializer()));// 设置缓存属性CacheProperties.Redis redisProperties = cacheProperties.getRedis();if (redisProperties.getTimeToLive() != null) {config = config.entryTtl(redisProperties.getTimeToLive());}if (!redisProperties.isCacheNullValues()) {config = config.disableCachingNullValues();}if (!redisProperties.isUseKeyPrefix()) {config = config.disableKeyPrefix();}return config;}@Beanpublic RedisCacheManager redisCacheManager(RedisTemplate<String, Object> redisTemplate,RedisCacheConfiguration redisCacheConfiguration,YudaoCacheProperties yudaoCacheProperties) {RedisConnectionFactory connectionFactory = Objects.requireNonNull(redisTemplate.getConnectionFactory());RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory,BatchStrategies.scan(yudaoCacheProperties.getRedisScanBatchSize()));return new TimeoutRedisCacheManager(cacheWriter, redisCacheConfiguration);}
}

解释

  • 启用缓存:@EnableCaching 激活 Spring Cache 功能。
  • 键前缀:自定义键前缀格式(如 cacheName:),使用单冒号分隔,避免工具(如 Redis Desktop Manager)显示问题。
  • 序列化:复用 YudaoRedisAutoConfiguration.buildRedisSerializer(),确保值以 JSON 格式存储。
  • 缓存属性
    • timeToLive:设置默认缓存过期时间(项目默认 1 小时)。
    • disableCachingNullValues:禁止缓存 null 值。
    • disableKeyPrefix:可选禁用键前缀。
  • RedisCacheManager:创建缓存管理器,基于 Redis 实现缓存存储。
  • 步骤 3:使用 Spring Cache 注解

    在 RoleServiceImpl 中,使用 @Cacheable 和 @CacheEvict 实现角色缓存。

@Service
public class RoleServiceImpl {@Resourceprivate RoleMapper roleMapper;@Cacheable(value = RedisKeyConstants.ROLE, key = "#id", unless = "#result == null")public RoleDO getRoleFromCache(Long id) {return roleMapper.selectById(id);}@Transactional(rollbackFor = Exception.class)@CacheEvict(value = RedisKeyConstants.ROLE, key = "#id")public void deleteRole(Long id) {RoleDO role = validateRoleForUpdate(id);roleMapper.deleteById(id);permissionService.processRoleDeleted(id);LogRecordContext.putVariable("role", role);}
}
  • 解释
    • @Cacheable
      • value = RedisKeyConstants.ROLE:指定缓存名称(对应 Redis 键前缀,如 role:)。
      • key = "#id":使用方法参数 id 作为缓存键(如 role:123)。
      • unless = "#result == null":避免缓存 null 值。
      • 执行逻辑:先检查 Redis 是否有缓存,若有则返回;否则执行方法并缓存结果。
    • @CacheEvict:在删除角色时,移除对应的缓存键(如 role:123),确保缓存与数据库一致。
    • 被动读策略:仅在查询时缓存数据(getRoleFromCache),更新或删除时清除缓存(deleteRole),避免缓存非必要数据。
步骤 4:缓存与数据库一致性

yudao 项目采用被动读策略:

  • 查询:从 Redis 获取数据,若无则从 MySQL 查询并缓存。
  • 更新/删除:更新 MySQL 后,删除 Redis 缓存,确保下次查询时重新从数据库加载。
  • 原因
    • 保证 Redis 和 MySQL 数据一致性。
    • 避免主动写入非必要数据,节省 Redis 存储空间。

2.在新项目中实现 Redis 缓存

2.1 项目结构

new-project/
├── src/
│   ├── main/
│   │   ├── java/
│   │   │   └── com/example/demo/
│   │   │       ├── config/
│   │   │       │   └── RedisConfig.java
│   │   │       ├── dao/
│   │   │       │   └── UserRedisDAO.java
│   │   │       ├── entity/
│   │   │       │   └── UserDO.java
│   │   │       ├── service/
│   │   │       │   ├── UserService.java
│   │   │       │   └── UserServiceImpl.java
│   │   │       └── constants/
│   │   │           └── RedisKeyConstants.java
│   │   └── resources/
│   │       └── application.yml
│   └── pom.xml

2.2 依赖配置

在 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><groupId>com.example</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.5</version><relativePath/></parent><dependencies><!-- Spring Boot Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Redis 依赖 --><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId><version>3.25.0</version></dependency><!-- Spring Cache 依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><!-- MyBatis-Plus 依赖 --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3</version></dependency><!-- MySQL 依赖 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><!-- Lombok 依赖 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency><!-- Hutool 工具库 --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.20</version></dependency></dependencies>
</project>

解释

  • spring-boot-starter-web:提供 Web 功能。
  • redisson-spring-boot-starter:支持 Redis 操作。
  • spring-boot-starter-cache:支持 Spring Cache 注解。
  • mybatis-plus-boot-starter:用于数据库操作。
  • mysql-connector-java:MySQL 数据库驱动。
  • lombok:简化代码。
  • hutool-all:提供 JSON 序列化等工具,模拟 yudao 的 JsonUtils。

2.3 配置 Redis 连接

在 application.yml 中配置 Redis 和数据库连接。

spring:redis:host: 127.0.0.1port: 6379database: 0datasource:url: jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=Asia/Shanghaiusername: rootpassword: rootcache:redis:time-to-live: 3600000 # 缓存默认过期时间 1 小时(毫秒)key-prefix: "cache:" # 缓存键前缀cache-null-values: false # 不缓存 null 值
mybatis-plus:mapper-locations: classpath*:/mapper/*.xml

解释

  • Redis 配置:与 yudao 一致,指定本地 Redis 服务器。
  • Cache 配置:设置默认过期时间为 1 小时,使用 cache: 前缀。
  • MySQL 配置:连接本地 MySQL 数据库(需创建 demo 数据库)。
  • MyBatis-Plus:配置 Mapper XML 文件路径。

2.4 配置 RedisTemplate 和 Spring Cache

创建 RedisConfig 类,配置 RedisTemplate 和 Spring Cache。

package com.example.demo.config;import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.cache.CacheProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheWriter;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;import java.time.Duration;@AutoConfiguration
@EnableCaching
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(factory);template.setKeySerializer(new StringRedisSerializer());template.setHashKeySerializer(new StringRedisSerializer());template.setValueSerializer(jsonSerializer());template.setHashValueSerializer(jsonSerializer());return template;}private RedisSerializer<Object> jsonSerializer() {RedisSerializer<Object> json = RedisSerializer.json();ObjectMapper mapper = (ObjectMapper) ReflectUtil.getFieldValue(json, "mapper");mapper.registerModule(new JavaTimeModule());return json;}@Bean@Primarypublic RedisCacheConfiguration redisCacheConfiguration(CacheProperties cacheProperties) {RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig();config = config.computePrefixWith(cacheName -> cacheProperties.getRedis().getKeyPrefix() + cacheName + ":");config = config.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jsonSerializer()));CacheProperties.Redis redisProperties = cacheProperties.getRedis();if (redisProperties.getTimeToLive() != null) {config = config.entryTtl(redisProperties.getTimeToLive());}if (!redisProperties.isCacheNullValues()) {config = config.disableCachingNullValues();}return config;}@Beanpublic RedisCacheManager redisCacheManager(RedisTemplate<String, Object> redisTemplate,RedisCacheConfiguration redisCacheConfiguration) {RedisConnectionFactory factory = redisTemplate.getConnectionFactory();RedisCacheWriter cacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(factory);return new RedisCacheManager(cacheWriter, redisCacheConfiguration);}
}
  • 解释
    • RedisTemplate:与 yudao 一致,使用字符串序列化键,JSON 序列化值,支持 LocalDateTime。
    • Spring Cache:启用 @EnableCaching,配置 RedisCacheConfiguration 使用 JSON 序列化和自定义键前缀。
    • RedisCacheManager:创建缓存管理器,基于 Redis 存储缓存。

注意:ReflectUtil 模拟 yudao 的反射操作,需替换为 Hutool 的 ReflectUtil 或直接修改 ObjectMapper:

import cn.hutool.core.util.ReflectUtil;

2.5 定义数据对象(UserDO)

创建 UserDO 类,表示用户信息。

package com.example.demo.entity;import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.time.LocalDateTime;@TableName("user")
@Data
public class UserDO {@TableIdprivate Long id;private String username;private String email;private LocalDateTime createTime;
}

解释:UserDO 映射数据库表 user,包含基本用户信息。需在 MySQL 中创建表:

CREATE TABLE user (id BIGINT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL,email VARCHAR(100),create_time DATETIME
);

2.6 定义 Redis 键常量

创建 RedisKeyConstants 类,定义 Redis 键。

package com.example.demo.constants;public interface RedisKeyConstants {String USER = "user:%s";
}

解释:定义用户缓存的键格式,如 user:123。

2.7 实现 Redis 数据访问对象(UserRedisDAO)

创建 UserRedisDAO 类,封装用户缓存操作。

package com.example.demo.dao;import cn.hutool.json.JSONUtil;
import com.example.demo.constants.RedisKeyConstants;
import com.example.demo.entity.UserDO;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Repository;import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;@Repository
public class UserRedisDAO {@Resourceprivate StringRedisTemplate stringRedisTemplate;public UserDO get(Long id) {String redisKey = formatKey(id);String value = stringRedisTemplate.opsForValue().get(redisKey);return JSONUtil.toBean(value, UserDO.class);}public void set(UserDO userDO) {String redisKey = formatKey(userDO.getId());userDO.setCreateTime(null); // 清理多余字段stringRedisTemplate.opsForValue().set(redisKey, JSONUtil.toJsonStr(userDO), 3600, TimeUnit.SECONDS);}public void delete(Long id) {String redisKey = formatKey(id);stringRedisTemplate.delete(redisKey);}private static String formatKey(Long id) {return String.format(RedisKeyConstants.USER, id);}
}

解释

  • 注入:使用 StringRedisTemplate 操作 JSON 字符串。
  • 方法
    • get:从 Redis 获取用户数据,反序列化为 UserDO。
    • set:将 UserDO 序列化为 JSON,设置 1 小时过期时间。
    • delete:删除指定用户的缓存。
  • JSON 处理:使用 Hutool 的 JSONUtil 替代 yudao 的 JsonUtils。

2.8 实现业务逻辑

创建 UserService 接口和 UserServiceImpl 实现类,支持编程式和声明式缓存。

package com.example.demo.service;import com.example.demo.entity.UserDO;public interface UserService {UserDO getUser(Long id); // 编程式缓存UserDO getUserFromCache(Long id); // 声明式缓存void deleteUser(Long id);
}
package com.example.demo.service;import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.example.demo.constants.RedisKeyConstants;
import com.example.demo.dao.UserRedisDAO;
import com.example.demo.entity.UserDO;
import com.example.demo.mapper.UserMapper;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;import javax.annotation.Resource;@Service
public class UserServiceImpl implements UserService {@Resourceprivate UserMapper userMapper;@Resourceprivate UserRedisDAO userRedisDAO;@Overridepublic UserDO getUser(Long id) {UserDO user = userRedisDAO.get(id);if (user != null) {return user;}user = userMapper.selectById(id);if (user != null) {userRedisDAO.set(user);}return user;}@Override@Cacheable(value = RedisKeyConstants.USER, key = "#id", unless = "#result == null")public UserDO getUserFromCache(Long id) {return userMapper.selectById(id);}@Override@CacheEvict(value = RedisKeyConstants.USER, key = "#id")public void deleteUser(Long id) {userMapper.deleteById(id);// 缓存通过 @CacheEvict 自动清除}
}
  • 解释
    • 编程式缓存(getUser):先查 Redis,若无则查数据库并缓存。
    • 声明式缓存(getUserFromCache):使用 @Cacheable,自动处理缓存逻辑。
    • 删除(deleteUser):删除数据库记录并通过 @CacheEvict 清除缓存。

相关文章:

  • 【ExcelVBA 】类模块学习从入门到放弃
  • SHAP分析+贝叶斯优化BP神经网络+新数据预测+K折交叉验证+相关性分析+孤立森林异常值处理,Matlab代码实现,作者:机器学习之心!
  • 【MPC控制】番外篇:MPC 与 机器学习/深度学习 —— 双雄会的相似与不同
  • ADS学习笔记(三) 瞬态仿真
  • C++学习之STL学习:string类常用接口的模拟实现
  • 李宏毅《机器学习2025》笔记 第二讲 —— AI Agent
  • vue3中computed计算属性和watch监听的异同点
  • 历年吉林大学保研上机真题
  • Python经典算法实战
  • 分布式缓存:BASE理论实践指南
  • conda 环境中opencv 报错
  • MySQL-----表的操作
  • SAP Commerce(Hybris)开发实战(二):登陆生成token问题
  • C#实现MCP Client 与 LLM 连接,抓取网页内容功能!
  • Windows系统部署Redis
  • 【医学影像 AI】TorchIO医学影像数据增强:从入门到精通的全面指南
  • Java 接口
  • 06-Web后端基础(java操作数据库)
  • Linux基础IO---缓冲区----文件系统----软硬链接
  • Python打卡训练营学习记录Day36
  • 个人可以备案哪些网站/大数据技术主要学什么
  • baidu网站建设/如何拥有自己的网站
  • 广州网站建设制作价格/线上推广策划方案范文
  • 网站建设彳金手指排名/今日头条淄博新闻
  • 泉州seo优化/seo网络优化是什么工作
  • 福州网站制作网站/企业管理咨询