Redis(二):缓存穿透及其解决方法(SpringBoot+mybatis-plus)(注解版)
·
一、代码
1.1 controller层
package com.study.sredis.stept001.controller;
import com.study.sredis.stept001.domain.User;
import com.study.sredis.stept001.service.IUserService;
import com.study.sredis.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/iuser")
public class ICacheTestController {
@Autowired
private IUserService iUserService;
@PostMapping("/getUser")
public R getUser(@RequestBody User user) {
User userInfo = iUserService.getByIdWithCache(user);
return R.ok(userInfo);
}
@PostMapping("/updateUser")
public R updateUser(@RequestBody User user) {
User userInfo = iUserService.updateWithCache(user);
return R.ok(userInfo);
}
@PostMapping("/deleteUser")
public R deleteUser(@RequestBody User user) {
boolean success = iUserService.removeWithCache(user);
return R.ok(success);
}
@PostMapping("/complexMethodWithCache")
public R complexMethodWithCache(@RequestBody User user) {
User userInfo = iUserService.complexMethodWithCache(user);
return R.ok(userInfo);
}
}
1.2 service层
1.2.1 servic
package com.study.sredis.stept001.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.study.sredis.stept001.domain.User;
/**
* 使用注解进行缓存
*/
public interface IUserService extends IService<User> {
User getByIdWithCache(User user);
User updateWithCache(User user);
boolean removeWithCache(User user);
User complexMethodWithCache(User user);
}
1.2.2 serviceImpl(重点)
package com.study.sredis.stept001.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.study.sredis.stept001.domain.User;
import com.study.sredis.stept001.mapper.userMapper;
import com.study.sredis.stept001.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.*;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* 使用注解进行缓存
*/
/**
* 注解五:@CacheConfig
* 原理:是 Spring 缓存抽象中的【类级别】注解,用于在类级别统一配置缓存相关的公共设置,避免在每个方法上重复配置相同的缓存参数。
* 核心特性:
* (1)类级别配置:在类级别统一配置缓存参数;
* (2)减少重复配置:避免在多个方法上重复相同的配置;
* (3)提高可维护性:集中管理缓存配置,便于修改和维护;
* (4)与方法级注解配合使用:为 @Cacheable、@CachePut、@CacheEvict 提供默认配置;
* 参数:
* (1)cacheNames / value (可选):指定类的默认缓存名称;
* (2)keyGenerator (可选):指定类的默认 key 生成器;
* (3)cacheManager (可选):指定类的默认缓存管理器;
* (4)cacheResolver (可选):指定类的默认缓存解析器;
*/
@Service
@CacheConfig(cacheNames = "users")
public class IUserServiceImpl extends ServiceImpl<userMapper, User> implements IUserService {
@Autowired
private userMapper userMapper;
/**
* 注解一:@Cacheable
* 原理:
* 参数:
* (1)value/cacheNames(必填): 指定缓存存储的区域,类似于命名空间,所有value=“XX”的缓存会存储在同一个缓存区域,可以定义多个:@Cacheable(value={"user","userDetail"}),类型: String[];
* (2)key(可选): 缓存键,定义缓存的唯一标识符,SpEL表达式,使用Spring Expression Language,类型: String,默认值:空字符串(使用默认键生成策略);
* (3)condition(可选): 缓存条件,在方法执行前判断是否应该缓存,类型: String (SpEL 表达式);
* (4)unless(可选): 否决缓存条件,在方法执行后判断是否应该缓存返回值,类型: String (SpEL 表达式);
* (5)keyGenerator(可选) - 自定义键生成器:自定义缓存键的生成逻辑,类型:String;
* (6)cacheManager(可选) - 缓存管理器:指定使用哪个缓存管理器,类型:String;
* (7)cacheResolver(可选) - 缓存解析器:自定义缓存解析逻辑,类型:String;
* (8)sync(可选) - 同步缓存:在多线程环境下同步缓存操作(主要用于本地缓存),默认为 false;
* 根据id查询用户信息
*/
@Override
@Cacheable(value = {"user", "userDetail"}, key = "#user.getId()", condition = "#user.getId() >0", unless = "#userInfo != null")
public User getByIdWithCache(User user) {
User userInfo = userMapper.selectById(user.getId());
return userInfo;
}
/**
* 使用自定义缓存key
*
* @return
*/
@Cacheable(value = "user", key = "'list'")
public List<User> getUserList() {
List<User> userList = userMapper.selectList(null);
return userList;
}
/**
* 条件缓存——只有当结果不为null时才缓存
*
* @param name
* @return
*/
@Cacheable(value = "user", key = "#name", unless = "#result==null")
public User getByName(String name) {
return lambdaQuery().eq(User::getUserName, name).one();
}
/**
* 注解二:@CachePut
* 原理:是 Spring 框架中用于更新缓存的注解,它的核心特点是总是执行方法体,然后将方法返回值存入缓存,确保缓存中的数据与数据库保持同步;
* 参数:
* (1)value/cacheNames(必填): 指定缓存存储的区域,类似于命名空间,所有value=“XX”的缓存会存储在同一个缓存区域,可以定义多个:@Cacheable(value={"user","userDetail"}),类型: String[];
* (2)key(可选): 缓存键,定义缓存的唯一标识符,SpEL表达式,使用Spring Expression Language,类型: String,默认值:空字符串(使用默认键生成策略);
* (3)condition(可选): 缓存条件,在方法执行前判断是否应该缓存,类型: String (SpEL 表达式);
* (4)unless(可选): 否决缓存条件,在方法执行后判断是否应该缓存返回值,类型: String (SpEL 表达式);
* (5)keyGenerator(可选) - 自定义键生成器:自定义缓存键的生成逻辑,类型:String;
* (6)cacheManager(可选) - 缓存管理器:指定使用哪个缓存管理器,类型:String;
* (7)cacheResolver(可选) - 缓存解析器:自定义缓存解析逻辑,类型:String;
* 根据id修改用户信息
*
* @param user
* @return
*/
@Override
@CachePut(value = "user", key = "#user.getId()")
public User updateWithCache(User user) {
int result = userMapper.updateById(user);
if (result > 0) {
return userMapper.selectById(user.getId());
}
return null;
}
/**
* 注解三:@CacheEvict
* 原理:是 Spring 框架中用于清除缓存的注解,主要用于在数据发生变更时移除对应的缓存条目,保证缓存与数据源的一致性
* 参数:
* (1)value / cacheNames (必需):指定要清除的缓存名称,可以指定多个缓存,类型: String[];
* (2)key (可选):指定要清除的缓存项的键,支持 SpEL 表达式,类型: String,默认值: 空字符串(清除该缓存下的所有条目);
* (3)keyGenerator (可选): 指定自定义的键生成器,类型: String,注意: 与 key 参数互斥;
* (4)cacheManager (可选):指定缓存管理器,类型: String;
* (5)cacheResolver (可选):指定自定义缓存解析器,类型: String,注意: 与 cacheManager 互斥;
* (6)condition (可选):指定条件,只有满足条件时才执行缓存清除,类型: String (SpEL 表达式);
* (7)unless (可选):否决条件,当表达式为 true 时不执行缓存清除,类型: String (SpEL 表达式),注意: 在 @CacheEvict 中较少使用,因为通常是根据条件执行清除;
* (8)allEntries (可选):是否清除缓存中的所有条目,类型: boolean,默认值: false,注意: 与 key 参数互斥,设置 allEntries=true 时不能指定 key;
* (9)beforeInvocation (可选):是否在方法执行前清除缓存,类型: boolean,默认值: false(方法执行成功后清除);
* <p>
* 根据id删除用户信息
*
* @param user
* @return
*/
@Override
@CacheEvict(value = "userDetail", key = "#user.getId()")
public boolean removeWithCache(User user) {
int result = userMapper.deleteById(user.getId());
return result > 0 ? true : false;
}
/**
* 注解四:@Caching
* 原理:是 Spring 缓存抽象中的组合注解,用于在同一个方法上组合多个缓存操作。当需要同时使用 @Cacheable、@CachePut、@CacheEvict 时,就需要使用 @Caching 注解。
* 核心特性:
* (1)组合多个缓存操作:支持同时配置多个缓存注解;
* (2)复杂缓存场景:适用于需要同时进行读、写、删除缓存的复杂业务;
* (3)简化配置:避免为复杂缓存逻辑编写多个方法;
*
* @param user
* @return
*/
@Override
@Caching(
cacheable = {
@Cacheable(value = "user", key = "#user.id"),
@Cacheable(value = "user2", key = "#user.userName")
},
put = {
@CachePut(value = "user3", key = "#result.id"),
@CachePut(value = "user2", key = "#result.id"),
},
evict = {
@CacheEvict(value = "user4", key = "#user.id")
}
)
public User complexMethodWithCache(User user) {
int result = userMapper.updateById(user);
if (result > 0) {
return userMapper.selectById(user.getId());
}
return null;
}
/**
* 清除所有user相关的缓存
*/
@CacheEvict(value = "user", allEntries = true)
public void clearAllUserCache() {
}
}
更多推荐
所有评论(0)