欢迎光临
我们一直在努力

苍穹外卖day07---Redis缓存优化与购物车功能实现

一.缓存菜品

1.问题1

当许多人同时访问我们的小程序,我们的程序可能在一个时间内进行非常多次数据库查询,这样会导致我们程序的数据库查询效率降低,因此我们通过Redis缓存功能进行解决该问题。

2.解决思路

当用户对菜品查询时,我们首先判断菜品是否缓存,如果缓存直接返回菜品即可,否则查询数据库,将查询到的菜品缓存,然后进行返回。

3.代码实现

@RestController("userDishController")
@RequestMapping("/user/dish")
@Slf4j
@Api(tags = "C端-菜品浏览接口")
public class DishController {
@Autowired
private DishService dishService;
@Autowired
private RedisTemplate redisTemplate;
/**
* 根据分类id查询菜品
*
* @param categoryId
* @return
*/
@GetMapping("/list")
@ApiOperation("根据分类id查询菜品")
public Result<List<DishVO>> list(Long categoryId) {
//根据分类id查询菜品是否缓存
String key = "dish_" + categoryId;
List<DishVO> list1 = (List<DishVO>) redisTemplate.opsForValue().get(key);
if(list1 != null && !list1.isEmpty()){
return Result.success(list1);
}
//如果没有缓存则去数据库中查询并缓存菜品
Dish dish = new Dish();
dish.setCategoryId(categoryId);
dish.setStatus(StatusConstant.ENABLE);
//查询起售中的菜品
List<DishVO> list = dishService.listWithFlavor(dish);
redisTemplate.opsForValue().set(key,list);
return Result.success(list);
}

4.问题2

当我们在管理端对菜品进行增删改操作以及起售停售时,我们应该将缓存删除掉,否则我们的增删改起售停售操作会起不到理想效果

5.解决思路

因为多个地方都需要删除缓存,所以我们将其抽象为一种方法,然后调用即可

6代码实现

private void cleanCache(String pattern){
Set keys = redisTemplate.keys(pattern);
redisTemplate.delete(keys);
}

因为修改操作设计的情况太过于复杂,可能涉及多个分类,所以我们直接将缓存全部删除即可。

二.缓存套餐

1.Spring Cache

Spring Cache 是 Spring 提供的一个缓存抽象框架,帮你把数据临时存起来,加快访问速度,减少重复查询。即可以实现我们上面的缓存菜品的功能。

常见注解:

2.代码实现思路

1.引入SpringCache以及redis依赖

2.启动类上加入@EnableCaching注解

3.list查询方法上加入@Cacheable注解

4.增删改起售停售等方法上加入@CacheEvict注解

代码非常简单,在此不过多赘述

三.添加购物车

1.需求分析

产品原型

接口设计

数据库设计

2.解决思路

添加购物车即点击加号时将菜品/套餐插入数据库。

应该注意:当购物车有这个商品时,应该是数量+1,我们将+1后的数量更新到数据库中,如果没有这个商品,直接将这个商品插入数据库。所以应该有一查询和插入和更新操作

3.代码实现

这里我们先写出代码的大体架构,即controller,mapper层,以及service层的大致逻辑

然后我们再去补充service层的逻辑实现

controller

@PostMapping("/add")
public Result shoppingCart(@RequestBody ShoppingCartDTO shoppingCartDTO){
shoppingCartService.shoppingCart(shoppingCartDTO);
return Result.success();
}

service

@Override
public void shoppingCart(ShoppingCartDTO shoppingCartDTO) {
ShoppingCart shoppingCart = new ShoppingCart();
BeanUtils.copyProperties(shoppingCartDTO,shoppingCart);
shoppingCart.setUserId(BaseContext.getCurrentId());
//查询,如果没有直接插入,有则数量加1
List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);
if (list != null && list.size() > 0){
//如果包含,则该商品数量加1,请你帮我实现
ShoppingCart cart = list.get(0);
cart.setNumber(cart.getNumber() + 1);
shoppingCartMapper.update(cart);
}//添加购物车,需要判断菜品是套餐还是菜品,因为接受参数不一样
else {
if(shoppingCartDTO.getDishId() != null){
//本次添加到购物车的是菜品
Dish dish = dishMapper.getById(shoppingCartDTO.getDishId());
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.setNumber(1);
shoppingCart.setCreateTime(LocalDateTime.now());
shoppingCartMapper.insert(shoppingCart);
}
}

mapper

@Mapper
public interface ShoppingCartMapper {
//查询
List<ShoppingCart> list(ShoppingCart shoppingCart);
//插入
@Insert("insert into shopping_cart (name, image, dish_id, setmeal_id, dish_flavor, number, amount, create_time, user_id) VALUES (#{name}, #{image}, #{dishId}, #{setmealId}, #{dishFlavor}, #{number}, #{amount}, #{createTime}, #{userId})")
void insert(ShoppingCart shoppingCart);

@Update("update shopping_cart set number = #{number} where id = #{id}")
void update(ShoppingCart cart);
@Delete("delete from shopping_cart where user_id = #{currentId}")
void clean(Long currentId);
@Delete("delete from shopping_cart where id = #{id}")
void deleteById(Long id);
}

我们在mapper模块的查询操作中,返回值是List集合,这里返回单个对象即可,我们这是多此一举吗?其实并不是。在实际开发中,这样的做法是我们的代码更具有韧性,可以重复利用。

我们上面实现了购物车的添加功能,但是购物车既然可以添加,那么就可以将某些菜品从购物车中去除,下面实现去除功能

controller

/**
* 删除购物车中一个商品
* @param shoppingCartDTO
* @return
*/
@PostMapping("/sub")
@ApiOperation("删除购物车中一个商品")
public Result sub(@RequestBody ShoppingCartDTO shoppingCartDTO){
log.info("删除购物车中一个商品,商品:{}", shoppingCartDTO);
shoppingCartService.subShoppingCart(shoppingCartDTO);
return Result.success();
}

service

@Override
public void subShoppingCart(ShoppingCartDTO shoppingCartDTO) {
ShoppingCart shoppingCart = new ShoppingCart();
BeanUtils.copyProperties(shoppingCartDTO,shoppingCart);
//设置查询条件,查询当前登录用户的购物车数据
shoppingCart.setUserId(BaseContext.getCurrentId());

List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);

if(list != null && list.size() > 0){
shoppingCart = list.get(0);

Integer number = shoppingCart.getNumber();
if(number == 1){
//当前商品在购物车中的份数为1,直接删除当前记录
shoppingCartMapper.deleteById(shoppingCart.getId());
}else {
//当前商品在购物车中的份数不为1,修改份数即可
shoppingCart.setNumber(shoppingCart.getNumber() – 1);
shoppingCartMapper.update(shoppingCart);
}
}
}

mapper

@Mapper
public interface ShoppingCartMapper {
//查询
List<ShoppingCart> list(ShoppingCart shoppingCart);
//插入
@Insert("insert into shopping_cart (name, image, dish_id, setmeal_id, dish_flavor, number, amount, create_time, user_id) VALUES (#{name}, #{image}, #{dishId}, #{setmealId}, #{dishFlavor}, #{number}, #{amount}, #{createTime}, #{userId})")
void insert(ShoppingCart shoppingCart);

@Update("update shopping_cart set number = #{number} where id = #{id}")
void update(ShoppingCart cart);
@Delete("delete from shopping_cart where user_id = #{currentId}")
void clean(Long currentId);
@Delete("delete from shopping_cart where id = #{id}")
void deleteById(Long id);
}

四.查看购物车

1.需求分析

产品原型

接口涉及

代码非常简单,普通的查询操作

2.代码实现

controller

@GetMapping("/list")
public Result list(){
List<ShoppingCart> list = shoppingCartService.list();
return Result.success(list);
}

service

@Override
public List<ShoppingCart> list() {
ShoppingCart shoppingCart = new ShoppingCart();
shoppingCart.setUserId(BaseContext.getCurrentId());
return shoppingCartMapper.list(shoppingCart);
}

五.清空购物车

思路非常简单,简单删除操作

代码实现

controller

@DeleteMapping("/clean")
public Result clean(){
shoppingCartService.clean();
return Result.success();
}

service

@Override
public void clean() {
shoppingCartMapper.clean(BaseContext.getCurrentId());
}

mapper

@Delete("delete from shopping_cart where id = #{id}")
void deleteById(Long id);

赞(0)
未经允许不得转载:171主机测评 » 苍穹外卖day07---Redis缓存优化与购物车功能实现
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址