1、命中
指是在应用程序中获取数据,取到后返回
2、失效
就是缓存有时间的,时间到了,就失效了
3、更新
应用程序把数据存到数据库中,在放回缓存中去
例如
我要取第一个商品信息,请求过来后先从cache里面获取,如果有直接返回。如果不存在会从mysql中,从db里面获取数据。从db里面获取数据成功之后,它会在把这部分数据,写到cache里面去,这样下次再获取商品信息,直接从cache里面获取了。你对数据库中的商品信息进行修改或者删除,那么对应的,你也需要对缓存里面的这一部分商品的信息进行更新和删除。因为缓存的信息源自于数据库,让他们保持一致。
@SpringBootApplication
EnableCaching是redis缓存第一部
@EnableCaching
public class SellApplication {
public static void main(String[] args) {
SpringApplication.run(SellApplication.class,args);
}
}
//get请求
@GetMapping("/list")
//使用VO中ResultVO对象
@CacheEvict(cacheNames = "product",key = "123")
public ResultVO list(){
//1、查询所有的上架商品
List<ProductInfo> productInfoList =productService.findUpAll();
//2、查询类目(一次性查询)
//精简方法,用的是(java8,lambda)
List<Integer> categoryTypeList= productInfoList.stream()
.map(e -> e.getCategoryType())
.collect(Collectors.toList());
List<ProductCategory> productCategoryList = categoryService.findByCategoryTypeIn(categoryTypeList) ;
//3、数据拼装
//(4)最外面一层是ProductVO是一个list,在外面定义下
List<ProductVO> productVOList =new ArrayList<>();
//(1)首先遍历类目
for (ProductCategory productCategory:productCategoryList){
ProductVO productVO= new ProductVO();
productVO.setCategoryType(productCategory.getCategoryType());
productVO.setCategoryName(productCategory.getCategoryName());
//(3)拷贝之后add一个list中去,在外面定义下
List<ProductInfoVO> productInfoVOList =new ArrayList<>();
//(2)下面在遍历商品详情
for (ProductInfo productInfo:productInfoList){
if (productInfo.getCategoryType().equals(productCategory.getCategoryType())){
ProductInfoVO productInfoVO =new ProductInfoVO();
//要写5个值,要写五遍,spring提供BeanUtils
//可以把productInfo拷贝到productInfoVO中去
BeanUtils.copyProperties(productInfo,productInfoVO);
productInfoVOList.add(productInfoVO);
//(3)拷贝之后add一个list中去,在外面定义下
}
}
productVO.setProductInfoVOList(productInfoVOList);
productVOList.add(productVO);
//(4)最外面一层是ProductVO是一个list,在外面定义下
}
return ResultVOUtil.success(productVOList);
}
@Data
//@JsonInclude(JsonInclude.Include.NON_NULL)
//Serializable添加缓存,
public class ResultVO<T> implements Serializable {
//序列号,可以保证id唯一
private static final long serialVersionUID = 3992098372355274267L;
/**错误码*/
private Integer code;
/**提示信息
*/
private String msg;
/**返回具体内容
*/
private T data;
}
为什么是乱码,是存储的时候进行序列号,存进去的是resultvo这个对象
如果这个时候在访问一次这个接口,就不会到这个断点来
就是第二次执行的时候,就没有在进入这个方法,下面整块代码都没有执行过,直接就返回了
返回的数据就是从redis中读出来的
将芒果冰价格改为21,但是缓存的里面的价格没有更改
在更新操作中加一个维护SellerProductController
更新就要换一个注解@CachePut,缓存就会跟新了
删除redis的注解@CacheEvict
@PostMapping("/save")
@CachePut(cacheNames = "product", key = "123")
//删除redis的注解
// @CacheEvict(cacheNames = "product", allEntries = true, beforeInvocation = true)
//新建一个对象,专门存储表单传递过来的对象ProductForm,表单验证方法
public ModelAndView save(@Valid ProductForm form,
BindingResult bindingResult,
Map<String, Object> map) {
if (bindingResult.hasErrors()) {
map.put("msg", bindingResult.getFieldError().getDefaultMessage());
map.put("url", "/sell/seller/product/index");
return new ModelAndView("common/error", map);
}
ProductInfo productInfo = new ProductInfo();
try {
//如果productId为空, 说明是新增,如果不加,传过的值为空,会显示空,
//先在数据库中查出来有一个初试 的值,然后再把前端传过来的值拷贝到productInfo对象
//这样就可以传过来新的值把旧的值覆盖掉了
//如果不为空就是更新
if (!StringUtils.isEmpty(form.getProductId())) {
productInfo = productService.findOne(form.getProductId());
} else {
//如果新增的话,要设置一下id
form.setProductId(KeyUtil.genUniqueKey());
}
//拷贝方法
BeanUtils.copyProperties(form, productInfo);
productService.save(productInfo);
} catch (SellException e) {
map.put("msg", e.getMessage());
map.put("url", "/sell/seller/product/index");
return new ModelAndView("common/error", map);
}
map.put("url", "/sell/seller/product/list");
return new ModelAndView("common/success", map);
}