后端学习笔记-缓存数据

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

在项目中的使用思路

相关推荐
愚昧之山绝望之谷开悟之坡1 分钟前
什么agentskill.io大白话说清楚
笔记
charlie1145141912 分钟前
通用GUI编程技术——图形渲染实战(三十八)——顶点缓冲与输入布局:GPU的第一个三角形
开发语言·c++·学习·图形渲染·win32
我想我不够好。26 分钟前
监控学习 4.29 1.5hour
学习
晓晓hh26 分钟前
JavaWeb学习——JUnit和日志
学习·junit·单元测试
小超同学你好35 分钟前
Transformer 30. MoCo:用「动量编码器 + 队列字典」把对比学习做成可扩展的“字典查找”
深度学习·学习·transformer
光影少年1 小时前
前端SSR和ssg区别
前端·vue.js·人工智能·学习·react.js
筱_智1 小时前
Docker学习-超详细-通俗易懂(从入门到精通)
学习·docker·容器
其实防守也摸鱼1 小时前
带你了解与配置phpmyadmin
笔记·安全·网络安全·pdf·编辑器·工具·调试
RENMinWanSui!1 小时前
Neo4j-Desktop2.0安装教程(更改安装路径)
笔记·neo4j·neo4j-desktop
噜噜噜阿鲁~1 小时前
python学习笔记 | 8.2、函数式编程-返回函数
笔记·python·学习