后端学习笔记-缓存数据

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

在项目中的使用思路

相关推荐
数据轨迹0012 小时前
AAAI Mesorch:频域增强+自适应剪枝相结合
经验分享·笔记·facebook·oneapi·twitter
Y00712 小时前
AT32F403AVGT7学习笔记
笔记·学习
摘星星的屋顶2 小时前
2026年1月19日~2026年1月25日周报
人工智能·深度学习·学习
刹那间的回眸x.y3 小时前
Jenkins学习
运维·学习·jenkins
柳鲲鹏3 小时前
WIN10禁止升级为WIN11
笔记
潇冉沐晴3 小时前
div3 970个人笔记
c++·笔记·算法
Just right3 小时前
安装RAGAS遇到的问题
笔记·python
求真求知的糖葫芦3 小时前
简明微波2-12耦合传输线分析学习笔记(五)对称均匀耦合线Z参数矩阵推导
笔记·学习·矩阵·射频工程
BlackWolfSky3 小时前
鸿蒙中级课程笔记2—状态管理V2—@ReusableV2装饰器:组件复用
笔记·华为·harmonyos