后端学习笔记-缓存数据

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

在项目中的使用思路

相关推荐
菜鸡儿齐7 小时前
Unsafe方法学习
java·python·学习
留白_12 小时前
MySQL学习(7)——存储过程
学习
小酒丸子13 小时前
AD学习笔记之异形焊盘
笔记·学习
renhongxia113 小时前
如何对海洋系统进行知识图谱构建?
人工智能·学习·语言模型·自然语言处理·自动化·知识图谱
知识分享小能手14 小时前
Redis入门学习教程,从入门到精通,Redis 数据操作:知识点详解与代码实战(2)
数据库·redis·学习
red_redemption14 小时前
自由学习记录(138)
学习
夏日听雨眠15 小时前
文件学习8
学习
炽烈小老头16 小时前
【每天学习一点算法 2026/03/17】括号生成
前端·学习·typescript
似水明俊德16 小时前
01-C#.Net-泛型-学习笔记
java·笔记·学习·c#·.net
今儿敲了吗16 小时前
python基础学习笔记第三章
笔记·python·学习