菜品管理模块day06
day06菜品管理
1、新增菜品
1.1、功能分析
- 点击新增菜品,进入添加菜品网页【标1】;
- 添加完成菜品名称和单价【标2】后,选择菜品所属的菜品分类【标4】【标5】(需要一个菜品分类选择列表功能);
- 为需要添加口味偏好的菜品添加特色口味【标6】和【标7】(需要一个口味选择列表功能,前端固定死了,后端省略),
- 点击【标8】为菜品添加图片(图片上产),图片上传后,自动执行图片下载(图片显示),这个功能前面已经完成;
- 菜品添加完成后,点击【标10】,向后端发送保存请求;
1.2、代码
Category_controller
/**
* 查找所有符合条件的数据列表
* @param categoryListDto dto
* @return Result<List<Category>>
*/
@GetMapping("/list")
@ApiOperation(value = "查找所有符合条件的数据列表" )
public Result<List<Category>> getList(CategoryListDto categoryListDto) {
log.info("CategoryListDto={}",categoryListDto);
//执行查询
List<Category> list= categoryService.list(categoryListDto);
return Result.success(list);
}
Service
List<Category> list(CategoryListDto categoryListDto);
Impl
@Override
public List<Category> list(CategoryListDto categoryListDto) {
//1.准备查询条件和排序规则
LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(categoryListDto.getType() != null,Category::getType,categoryListDto.getType());
queryWrapper.orderByAsc(Category::getSort).orderByDesc(Category::getUpdateTime);
//2.查询数据
List<Category> list = super.list(queryWrapper);
//3.返回数据
return list;
}
1.3、问题
因为Dish实体类不满足接收flavor参数,需要创建一个Dish的子类DishDto,用于封装口味数据
2、删除菜品
控制层
/**
* 删除指定ID集合的数据
* @param ids ids
* @return Result<String>
*/
@DeleteMapping
@ApiOperation(value = "根据ID删除当前记录")
public Result<String> deleteBatch(String[] ids) {
//log.info("ids={}",ids);
dishService.deleteBatch(ids);
return Result.success("删除成功");
}
接口层
void deleteBatch(String[] ids);
实现类
@Transactional
@Override
public void deleteBatch(String[] ids) {
//1.逐一遍历
for (String id : ids) {
//2.检查是否为售卖状态,售卖状态不允许删除
Dish dish = super.getById(id);
if (dish.getStatus().equals(StatusConstant.ENABLE)) {
//当前菜品处于起售中,不能删除
throw new DeletionNotAllowedException(dish.getName() + "," + MessageConstant.DISH_ON_SALE);
}
//3. 检查是否在套餐中关联了,关联了的菜品不允许删除
LambdaQueryWrapper<SetmealDish> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(SetmealDish::getDishId, id);
List<SetmealDish> setmealDisheList = setmealDishService.list(queryWrapper);
if (setmealDisheList != null && setmealDisheList.size() > 0) {
//当前菜品被套餐关联了,不能删除
throw new DeletionNotAllowedException(dish.getName() + "," + MessageConstant.DISH_BE_RELATED_BY_SETMEAL);
}
//4.允许删除
super.removeById( Long.valueOf(id));
}
}
3、菜品的状态修改(起售、停售)
控制层
/**
* 查询指定id的记录
* @param id id
* @return Result<Dish>
*/
@GetMapping("/{id}")
@ApiOperation(value = "查询指定id的记录" )
public Result<Dish> getByIdWithFlavor(@PathVariable long id) {
DishDto dishDto = dishService.getByIdWithFlavor(id);
log.info("查询到的数据为:{}", dishDto);
return Result.success(dishDto);
}
接口层
public DishDto getByIdWithFlavor(Long id);
实现类
@Override
public DishDto getByIdWithFlavor(Long id) {
//1.先根据id查询到对应的dish对象
Dish dish = this.getById(id);
//2.创建一个dishDao对象
DishDto dishDto = new DishDto();
//拷贝对象
BeanUtils.copyProperties(dish, dishDto);
//3.条件构造器,对DishFlavor表查询
LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
//根据dish_id来查询对应的菜品口味数据
queryWrapper.eq(DishFlavor::getDishId, id);
//获取查询的结果
List<DishFlavor> flavors = dishFlavorService.list(queryWrapper);
//并将其赋给dishDto
dishDto.setFlavors(flavors);
//4.作为结果返回给前端
return dishDto;
}
4、流式处理中map和peek的区别
4.1、什么是流式处理?
1.在JavaWeb中,流式处理(Stream Processing)是指对数据流进行连续、实时的处理。它允许你以连续的方式处理输入数据流,并在实时处理过程中逐步生成输出数据流。
2.在JavaWeb开发中,流式处理通常用于处理大规模数据、实时数据或者需要实时响应的场景。流式处理可以提供更高的性能和更低的延迟,因为它可以同时处理数据流的不同部分,而不需要等待全部数据到达。
3.流式处理可以通过使用Java 8引入的Stream API来实现。Stream API是Java的一种函数式编程方式,它提供了一套丰富的操作方法,可以方便地对数据流进行转换、过滤、映射等操作。
4.通过使用流式处理,你可以将数据的处理过程以流水线的方式进行组合,每个处理步骤都可以独立执行,从而实现高效的数据处理和分析。同时,流式处理还提供了一些高级功能,如窗口计算、聚合操作和事件处理等,可以满足不同场景下的需求。
4.2、map和peek的使用方式
map:
- 功能:map方法用于将流中的每个元素映射到另一个元素上,生成一个新的流。
- 用法:map方法接收一个Function函数式接口作为参数,该函数接收一个输入元素,并返回一个经过处理后的输出元素。
Stream<Integer> numbers = Stream.of(1, 2, 3, 4, 5);
Stream<Integer> squaredNumbers = numbers.map(n -> n * n);
peek:
- 功能:peek方法用于在流的处理过程中执行一个操作,类似于观察者模式的观察者。它不会改变流中的元素,而是提供一个机会在每个元素上执行一些副作用操作,例如打印元素或记录日志。
- 用法:peek方法接收一个Consumer函数式接口作为参数,该函数接收一个输入元素,并对其执行副作用操作,但不返回任何结果。
Stream<String> names = Stream.of("Alice", "Bob", "Charlie");
names.peek(System.out::println).forEach(name -> {});
总结:
- map方法用于对输入流中的每个元素进行转换并生成一个新的流。
- peek方法用于在流的处理过程中执行副作用操作,不会改变流中的元素。
- 两者的区别在于,map方法会返回一个新的流,而peek方法不会。