栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

使用Spring本地缓存注解 练习【增删改查案例】时发现的问题,以及解决方案

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

使用Spring本地缓存注解 练习【增删改查案例】时发现的问题,以及解决方案


文章目录
  • 概述
  • 疑惑点
  • 案例说明
    • 1.验证:【批量查询+修改】 指向key相同结果是否生效?
    • 2.验证:【单条查询+单条修改/单条删除】 指向key相同结果是否生效?
    • 3.验证:【批量查询+修改】指向key不相同结果是否生效?
  • 本人其他相关文章链接

概述

本文主要是为了个人练习spring的缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】,以及总结个人在使用过程中发现的疑惑点,以及如何解决等思路,另外该文章不会写的特别繁琐、复杂,如果具体想查看某个注解的详细使用方式请单个注解去CSDN查询即可,我这边只是为了个人总结,言简意赅那种。

疑惑点

思考:批量查询我放在缓存key=‘list’里面,而我在执行部分更新或者删除功能时,设置的key=’#id’,我以为部分更新和修改操作后,再次批量查询的结果就应该是更新缓存后的结果,实践才发现查询的还是旧数据,但我已经确认部分更新和删除操作缓存已经走进去了,为啥会这样?

答案:最终缓存中存储的内容格式为:Entry 形式。
大白话讲:就是每个key,对应不同的表存储不同的信息,key=‘list’和key=’#id’,如果你不做关联它两一点关系都没有,所以如果你想实现更新操作能够修改并影响到批量查询的缓存结果,那么请把批量查询和修改功能对应相同的key

案例说明

EhCacheController

package com.example.demo.controller;

import com.example.demo.bean.UserModel;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;


@RestController
@RequestMapping("/ehCache")
public class EhCacheController {
    private ConcurrentHashMap> cache = new ConcurrentHashMap<>();

    @PostConstruct
    public void initCacheUserModelList() {
        List userModelList = new ArrayList<>();
        userModelList.add(new UserModel(1, "Chris", 40, "中国上海"));
        userModelList.add(new UserModel(2, "Marry", 20, "中国北京"));
        userModelList.add(new UserModel(3, "Mike", 30, "中国广州"));
        cache.put("userModelList", userModelList);
    }

    
    @GetMapping("/list")
    @Cacheable(cacheNames = "user_model", key = "'list_all'")
    public List list() {
        List userModelList = cache.get("userModelList");
        System.out.println("从数据库获取用户列表");
        userModelList.stream().forEach(System.out::println);
        return userModelList;
    }

    
    @GetMapping("/find/{id}")
    @Cacheable(cacheNames = "user_model", key = "'find_1'")
    public UserModel find(@PathVariable int id) {
        UserModel userModel = new UserModel(1, "Chris", 40, "中国上海");
        System.out.println("从数据库获取用户");
        return userModel;
    }

    
    @GetMapping("/findById/{id}")
    @Cacheable(cacheNames = "user_model", key = "#id")
    public UserModel findById(@PathVariable int id) {
        UserModel userModel = new UserModel(id, "Chris", 40, "中国上海");
        System.out.println("从数据库获取用户:" + id);
        return userModel;
    }

    
    @PutMapping("/update")
    @CachePut(cacheNames = "user_model", key = "#userModel.id")
    public UserModel update(@RequestBody UserModel userModel) {
        userModel = new UserModel(userModel.getId(), "Jerry", 28, "哈尔滨");
        System.out.println("从缓存中修改用户,key = #userModel.id:" + userModel);
        return userModel;
    }
    
    @PutMapping("/update2")
    @CachePut(cacheNames = "user_model", key = "'list_all'")
    public List update2(@RequestBody UserModel userModel) {
        List userModelList = cache.get("userModelList");
        Iterator iterator = userModelList.iterator();
        while(iterator.hasNext()){
            UserModel item = iterator.next();
            if (item.getId() ==  userModel.getId()) {
                iterator.remove();  //注意这个地方
            }
        }
        userModelList.add(new UserModel(userModel.getId(), userModel.getName(), userModel.getAge(), userModel.getAddress()));
        cache.put("userModelList", userModelList);
        System.out.println("从缓存中修改用户,key = 'list_all'");
        cache.get("userModelList").stream().forEach(System.out::println);
        return userModelList;
    }

    
    @DeleteMapping("/delete/{id}")
    @CacheEvict(cacheNames = "user_model", key = "#id")
    public String delete(@PathVariable int id) {
        System.out.println("从缓存删除用户:" + id);
        return "Delete User " + id + " success.";
    }
}
1.验证:【批量查询+修改】 指向key相同结果是否生效?

答案:生效

第1步:调用批量查询,@Cacheable(cacheNames = “user_model”, key = “‘list_all’”)

第2步:调用更新,@CachePut(cacheNames = “user_model”, key = “‘list_all’”)

第3步:再次调批量查询,@Cacheable(cacheNames = “user_model”, key = “‘list_all’”)

第4步:看控制台打印

总结:已经走了本地缓存,因为咱们前后调用2次批量查询,但控制台只打印一次。

2.验证:【单条查询+单条修改/单条删除】 指向key相同结果是否生效?

答案:生效

第1步:调用单条查询,@Cacheable(cacheNames = “user_model”, key = “#id”)

第2步:调用删除,@CacheEvict(cacheNames = “user_model”, key = “#id”)

第3步:再次调用单条查询,@Cacheable(cacheNames = “user_model”, key = “#id”)

第4步:看控制台打印

总结:
正常第2次单条查询会走缓存,且控制台不会打印,但由于单条查询后 =》 删除 =》 再单条查询,所以单条查询打印了2次,等第3次再次调用单条查询后续就不会打印了

3.验证:【批量查询+修改】指向key不相同结果是否生效?

答案:不生效

第1步:调用批量查询,@Cacheable(cacheNames = “user_model”, key = “‘list_all’”)

第2步:调用更新,@CachePut(cacheNames = “user_model”, key = “#userModel.id”)

第3步:再次调用批量查询,@Cacheable(cacheNames = “user_model”, key = “‘list_all’”)

第4步:看控制台打印

总结:
结论:执行修改后查询的还是旧数据
原因:最终缓存中存储的内容格式为:Entry 形式。因为指向的key不相同,实际相当于保存了不同的数据,所以如果想影响相同的数据,请指向相同的key才行。

本人其他相关文章链接

1.Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项

2.使用Spring本地缓存注解 练习【增删改查案例】时发现的问题,以及解决方案

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/914406.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号