后端学习笔记-缓存数据

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();
    }

在项目中的使用思路

相关推荐
RainCity38 分钟前
Java Swing 自定义组件库分享(七)
java·笔记·后端
闫记康41 分钟前
Linux学习day5
linux·chrome·学习
一楼的猫1 小时前
从工具链视角对比:番茄作家助手 vs 第三方写作辅助方案
java·服务器·开发语言·前端·学习·chatgpt·ai写作
東隅已逝,桑榆非晚1 小时前
字符函数和字符串函数
c语言·笔记
他们叫我阿冠1 小时前
实习前自我培训-Day1学习
学习
Upsy-Daisy2 小时前
AI Agent 项目学习笔记(七):RAG 高级扩展——过滤检索、PgVector 与云知识库
人工智能·笔记·学习
柿柿快乐2 小时前
Redis 入门第一课:全局命令、内部编码与单线程模型
redis·学习·缓存·基础教学
智者知已应修善业3 小时前
【51单片机LED闪烁10次数码管显示0-9】2023-12-14
c++·经验分享·笔记·算法·51单片机
Lucky_ldy3 小时前
C语言学习:文件操作
学习
智者知已应修善业3 小时前
【51单片机2按键控制1个敞亮LED灯闪烁和熄灭】2023-11-3
c++·经验分享·笔记·算法·51单片机