后端学习笔记-缓存数据

Redis直接缓存

对于分类查询操作而言,在用户端这个接口需要频繁被调用,所以可以以分类id为key,菜品为值来存在redis当中

java 复制代码
/**
     * 根据分类id查询菜品
     *
     * @param categoryId
     * @return
     */
    @GetMapping("/list")
    @ApiOperation("根据分类id查询菜品")
    public Result<List<DishVO>> list(Long categoryId) {
        // 构造Redis的key
        String key ="dish_"+categoryId;
        List<DishVO> list = (List<DishVO>) redisTemplate.opsForValue().get(key);
        // 查询Redis中是否存在菜品数据
        if(list!=null && list.size()>0){
            // 存在,直接返回缓存中的数据
            return Result.success(list);
        }
        // 不存在,查询数据库
        Dish dish = new Dish();
        dish.setCategoryId(categoryId);
        dish.setStatus(StatusConstant.ENABLE);//查询起售中的菜品

        list = dishService.listWithFlavor(dish);
        // 缓存数据
        redisTemplate.opsForValue().set(key,list);

        return Result.success(list);
    }

对于管理端拥有的增删改三个操作,如果在数据库层面改了,缓存没有清理,就会导致用户读到的是脏数据,所以在进行三类操作时需要清理掉缓存数据

封装一个清理的函数

java 复制代码
/**
     * 清理缓存
     * @param pattern
     */
    private void cleanCache(String pattern){
        Set keys = redisTemplate.keys(pattern);
        redisTemplate.delete(keys);
    }

在删改操作中直接调用

java 复制代码
/**
     * 批量删除
     * @param ids
     * @return
     */
    @DeleteMapping
    @ApiOperation("菜品批量删除")
    public Result delete(@RequestParam List<Long> ids){
        log.info("菜品批量删除:{}",ids);
        dishService.deleteBatch(ids);

        // 清理缓存
        cleanCache("dish_*");
        return Result.success();
    }

/**
     * 更新菜品
     * @param dishDTO
     * @return
     */
    @PutMapping
    @ApiOperation("更新菜品")
    public Result update(@RequestBody DishDTO dishDTO){
        log.info("更新菜品:{}",dishDTO);
        dishService.updateWithFlavor(dishDTO);

        // 清理缓存
        cleanCache("dish_*");
        return Result.success();
    }
/**
     * 起售、停售菜品
     * @param status
     * @param id
     * @return
     */
    @PostMapping("/status/{status}")
    @ApiOperation("起售、停售菜品")
    public Result startOrStop(@PathVariable Integer status,Long id){
        log.info("起售、停售菜品:{}",id);
        dishService.startOrStop(status,id);

        // 清理缓存
        cleanCache("dish_*");
        return Result.success();
    }

在上述操作中因为涉及到多个菜品需要更新(删除操作,他们可能处于同一个分类也可能处于不同分类)或是更新菜品时可能是更新分类id,这样的时候都需要先查询了,得不偿失,可以直接清楚所有的分类缓存

增加菜品时直接只更新相应的分类id即可

java 复制代码
/**
     * 新增菜品
     * @param dishDTO
     * @return
     */
    @PostMapping
    @ApiOperation("添加菜品")
    public Result save(@RequestBody DishDTO dishDTO){
        log.info("添加菜品:{}",dishDTO);
        dishService.saveWithFlavor(dishDTO);

        // 清理缓存
        String key = "dish_" + dishDTO.getCategoryId();
        cleanCache(key);
        return Result.success();
    }

Spring Cache

注解使用

EnableCaching
java 复制代码
@Slf4j
@SpringBootApplication
@EnableCaching // 开启缓存功能
public class CacheDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(CacheDemoApplication.class,args);
        log.info("项目启动成功...");
    }
}
CachePut
java 复制代码
@PostMapping
    @CachePut(cacheNames = "userCache",key = "#user.id") //如果使用Spring Cache缓存数据,key的生成为:userCache::id, 从形参获取参数
    //@CachePut(cacheNames = "user",key = "#result.id") // 对象导航,从返回值获取参数
    //@CachePut(cacheNames = "user",key = "#p0") // 使用参数位置,从第一个参数获取参数
    //@CachePut(cacheNames = "user",key = "#a0") // 使用参数位置,从第一个参数获取参数
    //@CachePut(cacheNames = "user",key = "root.arg[0].id") // 使用参数位置,从第一个参数获取参数
    public User save(@RequestBody User user){
        userMapper.insert(user);
        return user;
    }
Cacheable
java 复制代码
@GetMapping
    @Cacheable(cacheNames = "userCache",key = "#id") // key生成 userCache::2
    public User getById(Long id){
        User user = userMapper.getById(id);
        return user;
    }
CacheEvict
java 复制代码
@DeleteMapping
    @CacheEvict(cacheNames = "userCache",key = "#id") // key生成 userCache::2
    public void deleteById(Long id){
        userMapper.deleteById(id);
    }

	@DeleteMapping("/delAll")
    @CacheEvict(cacheNames = "userCache",allEntries = true) // 删除所有缓存userCache::*
    public void deleteAll(){
        userMapper.deleteAll();
    }

在项目中的使用思路

相关推荐
Oll Correct28 分钟前
Adobe illustrator 案例十二:视频播放(Media & Video)图标绘制
笔记·ui·adobe·illustrator
橙橙笔记1 小时前
QT的学习第四部分
linux·qt·学习·音视频
叼烟扛炮2 小时前
Linux 学习笔记(五十四):内网穿透实战——用 frp 让外网访问你的私人电脑
linux·服务器·网络·笔记·学习
在猴站学算法2 小时前
(《统计学习方法》(第2版) 李航)第2章 感知机算法
学习·算法·机器学习·统计学习
旖旎夜光2 小时前
【C++ 基础入门】C++ 继承(上):概念、切片、隐藏、默认成员函数与友元
c++·笔记·学习
Godspeed Zhao2 小时前
从零开始学AI24——无监督学习之K均值
学习·机器学习
叼烟扛炮2 小时前
[LangChain] 学习笔记(05):提示词模板(Prompt)与少样本注入(Few-Shot)实战
linux·人工智能·笔记·学习·langchain·prompt
La Pulga15 小时前
【FreeRTOS源码学习笔记】任务延时列表
笔记·mcu·学习·嵌入式·freertos·实时操作系统
楚山之石16 小时前
【JCO】mpMRI 先行替代 TURBT 初始分期:BladderPath 随机试验让 MIBC 患者提前 45 天得到正确治疗
人工智能·学习·mri·医学影像
Peter-OK19 小时前
PostgreSQL学习笔记(入门-进阶-精通说明)
笔记·学习·postgresql