闽公网安备 35020302035485号
.删除缓存
<!-- redis使用 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
2、编写自定义aop注解和切面/**
*延时双删
**/
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.METHOD)
public @interface ClearAndReloadCache {
String name() default "";
}
ClearAndReloadCacheAspect延时双删切面
@Aspect
@Component
publicclass ClearAndReloadCacheAspect {
@Autowired
private StringRedisTemplate stringRedisTemplate;
/**
* 切入点
*切入点,基于注解实现的切入点 加上该注解的都是Aop切面的切入点
*
*/
@Pointcut("@annotation(com.pdh.cache.ClearAndReloadCache)")
public void pointCut(){
}
/**
* 堆代码 duidaima.com
* 环绕通知
* 环绕通知非常强大,可以决定目标方法是否执行,什么时候执行,执行时是否需要替换方法参数,执行完毕是否需要替换返回值。
* 环绕通知第一个参数必须是org.aspectj.lang.ProceedingJoinPoint类型
* @param proceedingJoinPoint
*/
@Around("pointCut()")
public Object aroundAdvice(ProceedingJoinPoint proceedingJoinPoint){
System.out.println("----------- 环绕通知 -----------");
System.out.println("环绕通知的目标方法名:" + proceedingJoinPoint.getSignature().getName());
Signature signature1 = proceedingJoinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature)signature1;
Method targetMethod = methodSignature.getMethod();//方法对象
ClearAndReloadCache annotation = targetMethod.getAnnotation(ClearAndReloadCache.class);//反射得到自定义注解的方法对象
String name = annotation.name();//获取自定义注解的方法对象的参数即name
Set<String> keys = stringRedisTemplate.keys("*" + name + "*");//模糊定义key
stringRedisTemplate.delete(keys);//模糊删除redis的key值
//执行加入双删注解的改动数据库的业务 即controller中的方法业务
Object proceed = null;
try {
proceed = proceedingJoinPoint.proceed();
} catch (Throwable throwable) {
throwable.printStackTrace();
}
//开一个线程 延迟1秒(此处是1秒举例,可以改成自己的业务)
// 在线程中延迟删除 同时将业务代码的结果返回 这样不影响业务代码的执行
new Thread(() -> {
try {
Thread.sleep(1000);
Set<String> keys1 = stringRedisTemplate.keys("*" + name + "*");//模糊删除
stringRedisTemplate.delete(keys1);
System.out.println("-----------1秒钟后,在线程中延迟删除完毕 -----------");
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
return proceed;//返回业务代码的值
}
}
3、application.ymlserver:
port: 8082
spring:
# redis setting
redis:
host: localhost
port: 6379
# cache setting
cache:
redis:
time-to-live: 60000 # 60s
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test
username: root
password: 1234
# mpsetting
mybatis-plus:
mapper-locations: classpath*:com/pdh/mapper/*.xml
global-config:
db-config:
table-prefix:
configuration:
# logofsql
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# hump
map-underscore-to-camel-case: true
4、user_db.sql脚本DROP TABLE IF EXISTS `user_db`; CREATE TABLE `user_db` ( `id` int(4) NOT NULL AUTO_INCREMENT, `username` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL, PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic; -- ---------------------------- -- Records of user_db -- ---------------------------- INSERT INTO `user_db` VALUES (1, '张三'); INSERT INTO `user_db` VALUES (2, '李四'); INSERT INTO `user_db` VALUES (3, '王二'); INSERT INTO `user_db` VALUES (4, '麻子'); INSERT INTO `user_db` VALUES (5, '王三'); INSERT INTO `user_db` VALUES (6, '李三');5、UserController
/**
* 用户控制层
*/
@RequestMapping("/user")
@RestController
publicclass UserController {
@Autowired
private UserService userService;
@GetMapping("/get/{id}")
@Cache(name = "get method")
//@Cacheable(cacheNames = {"get"})
public Result get(@PathVariable("id") Integer id){
return userService.get(id);
}
@PostMapping("/updateData")
@ClearAndReloadCache(name = "get method")
public Result updateData(@RequestBody User user){
return userService.update(user);
}
@PostMapping("/insert")
public Result insert(@RequestBody User user){
return userService.insert(user);
}
@DeleteMapping("/delete/{id}")
public Result delete(@PathVariable("id") Integer id){
return userService.delete(id);
}
}
6、UserService/**
* service层
*/
@Service
publicclass UserService {
@Resource
private UserMapper userMapper;
public Result get(Integer id){
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getId,id);
User user = userMapper.selectOne(wrapper);
return Result.success(user);
}
public Result insert(User user){
int line = userMapper.insert(user);
if(line > 0)
return Result.success(line);
return Result.fail(888,"操作数据库失败");
}
public Result delete(Integer id) {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(User::getId, id);
int line = userMapper.delete(wrapper);
if (line > 0)
return Result.success(line);
return Result.fail(888, "操作数据库失败");
}
public Result update(User user){
int i = userMapper.updateById(user);
if(i > 0)
return Result.success(i);
return Result.fail(888,"操作数据库失败");
}
}
三、测试验证




