一.缓存菜品
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);