苍穹外卖day7 缓存菜品 SpringCache缓存套餐 增删改查购物车

发布于:2025-02-19 ⋅ 阅读:(16) ⋅ 点赞:(0)

缓存菜品

为了避免后端访问数据库压力过大 采用redis中间件来缓存数据 减轻访问压力

学完以后也不是白学 各有各的好处 这个起码在明面上可以直接看出来小程序上的显示效果 

更直观展示查询结果和删除操作 需要注意 在增删改的时候都需要把缓存数据全部清除 否则

会导致数据不同步 小程序端上显示了停售的菜品 代表当前前端从redis中访问缓存并非从数据库里访问数据

    用户层dishcontroller
    @GetMapping("/list")
    @ApiOperation("根据分类id查询菜品")
//    @Cacheable(cacheNames = "dishCache",key = "#categoryId")///key:dishCache::categoryId
    public Result<List<DishVO>> list(Long categoryId) {
        //构造redis中的key 规则:dish_分类id
        String key = "dish_" + categoryId;
        //查询redis中是否存在菜品数据
        List<DishVO> list = (List<DishVO>) redisTemplate.opsForValue().get(key);
        if(list != null && list.size() > 0){
            //如果存在 就直接返回 无需查询数据库
            return Result.success(list);
        }

        Dish dish = new Dish();
        dish.setCategoryId(categoryId);
        dish.setStatus(StatusConstant.ENABLE);//查询起售中的菜品
        //如果不存在 查询数据库 把查询到的数据放入redis里
        list = dishService.listWithFlavor(dish);
        redisTemplate.opsForValue().set(key,list);
        //把集合序列化为redis字符串
        return Result.success(list);
    }

预防白学 先从SpringCache学起 解放硬编码 使用注解的方式代替

    @PostMapping
    @CachePut(cacheNames = "userCache",key = "#user.id")
//    @CachePut(cacheNames = "userCache",key = "#result.id")//返回结果取值
//    @CachePut(cacheNames = "userCache",key = "#p0.id")
//    @CachePut(cacheNames = "userCache",key = "#a0.id")
//    @CachePut(cacheNames = "userCache",key = "#root.args[0].id")
    //要实现动态key springEl 和方法形参一致
    //UserCache::id(不同主键id 1 2 3..)
    public User save(@RequestBody User user){
        userMapper.insert(user);
        return user;
    }
    CachePut

SpringCache基于代理技术 查询代理对象在缓存中的属性 不直接调用后端服务器的方法 

如果缓存(redis)没有该数据 通过反射调用后端控制层方法 这次是从数据库查找到当前数据

并且把当前数据库数据放到缓存redis里

    @GetMapping
    @Cacheable(cacheNames = "userCache",key = "#id")//key的动态生成 userCache:id
    public User getById(Long id){
        User user = userMapper.getById(id);
        return user;
    }

 CacheEvict 要删除数据库里的数据 先调用方法删除数据

redis再用动态代理反射删除缓存里的数据

	@DeleteMapping("/delAll")
    @CacheEvict(cacheNames = "userCache",key = "#id")//key的动态生成 userCache:id
    public void deleteAll(){
        userMapper.deleteAll();
    }

SpringCache缓存套餐

增删改查购物车

增购物车

进行操作时 三步 1 判断当前购物车加入商品是否已经存在 2 如果已经存在 就把数量加1 

3 如果不存在 则需要判断其商品是菜品还是套餐 再根据对应逻辑插入数据

@Service
@Slf4j
public class ShoppingCartServicelmpl implements ShoppingCartService {


    @Autowired
    private ShoppingCartMapper shoppingCartMapper;
    @Autowired
    private DishMapper dishMapper;
    @Autowired
    private SetmealMapper setmealMapper;
    /**
     * 添加购物车
     * @param shoppingCartDTO
     */
    public void addShoppingCartCart(ShoppingCartDTO shoppingCartDTO) {
        //判断当前加入购物车商品是否已经存在
        ShoppingCart shoppingCart = new ShoppingCart();
        BeanUtils.copyProperties(shoppingCartDTO,shoppingCart);
        //用户id被jwt拦截器拦截 可以在Threadlocal里直接找到userid
        Long userId = BaseContext.getCurrentId();
        shoppingCart.setUserId(userId);

        List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);
        //如果已经存在 只需要把数量加一
        if(list != null && list.size() > 0){
            ShoppingCart cart = list.get(0);
            cart.setNumber(cart.getNumber() + 1);//update shopping_cart set number = ? where id = ?
            shoppingCartMapper.updateNumber(cart);
        }else {
            //不存在则插入一条购物车数据
            //判断本次添加到购物车的是菜品还是套餐
            Long dishId = shoppingCartDTO.getDishId();
            if(dishId != null){
                //如果非空 表示是菜品
                Dish dish = dishMapper.getById(dishId);

                shoppingCart.setName(dish.getName());
                shoppingCart.setImage(dish.getImage());
                shoppingCart.setAmount(dish.getPrice());
            }else{
                //本次添加的是套餐
                Long setmealId = shoppingCartDTO.getSetmealId();

                Setmeal setmeal = setmealMapper.getById(setmealId);
                shoppingCart.setName(setmeal.getName());
                shoppingCart.setImage(setmeal.getImage());
                shoppingCart.setAmount(setmeal.getPrice());
            }
            shoppingCart.setCreateTime(LocalDateTime.now());
            shoppingCart.setNumber(1);
            shoppingCartMapper.insert(shoppingCart);
        }
    }
}

查购物车

流程比较通用

    Controller层
    @GetMapping("/list")
    @ApiOperation("查看购物车")
    public Result<List<ShoppingCart>> list(){
        List<ShoppingCart> list = shoppingCartService.showShoppingCart();
        return Result.success(list);
    }
    业务层声明接口
    /**
     * 查看购物车
     * @return
     */
    List<ShoppingCart> showShoppingCart();
    业务层实现
    /**
     * 查看购物车
     * @return
     */
    public List<ShoppingCart> showShoppingCart() {
        //获取到当前用户的userId
        Long userId = BaseContext.getCurrentId();
        ShoppingCart shoppingCart = ShoppingCart.builder()
                .userId(userId)
                .build();
        List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);
        return list;
    }
    Mapper层
    在增加购物车就已经有查询操作 这里调用其查询sql
    /**
     * 动态条件查询
     * @param shoppingCart
     * @return
     */
    List<ShoppingCart> list(ShoppingCart shoppingCart);

    <select id="list" resultType="com.sky.entity.ShoppingCart">
        select * from shopping_cart
        <where>
            <if test="userId != null">
                and user_id = #{userId}
            </if>
            <if test="setmealId != null">
                and setmeal_id = #{setmealId}
            </if>
            <if test="dishId != null">
                and dish_id = #{dishId}
            </if>
            <if test="dishFlavor != null">
                and dish_flavor = #{dishFlavor}
            </if>
        </where>
    </select>

 清除购物车

和之前开发的流程基本一致 

controller service接口调用 service层实现删除方法 删除操作在Mapper里声明接口 在xml里具体实现sql(这个比较简单 直接在Mapper上的声明方法上注解@Delete)

加油加油 继续新的一天 去看看八股!


网站公告

今日签到

点亮在社区的每一天
去签到