效果展示:
目录
一、文件上传下载 50
1.1文件上传 50编辑
1.2文件下载
1.3文件上传下载---文件上传代码实现1
1.4文件上传下载---文件上传代码实现2
1.5文件上传下载---文件下载代码实现 53
二、新增菜品 54
2.1需求分析 54
2.2数据模型
2.3新增菜品---代码开发---准备工作&梳理交互过程 55
2.4新增菜品---代码开发---查询分类数据 56
2.5新增菜品---代码开发---接收页面提交的数据 57
2.6新增菜品---代码开发---保存数据到菜品表和菜品口味表(操作多张表的处理) 58
2.7新增菜品---代码开发---功能测试 59
三、菜品信息分页查询 60
3.1需求分析 60
3.2代码开发---梳理交互过程 61
3.3菜品信息分页查询---代码开发2(菜品分类的完善)62
3.5菜品信息分页查询---功能测试 63
四、修改菜品 64
4.1需求分析 64
4.2代码开发---梳理交互过程 64
4.3修改菜品---代码开发---根据id查询菜品信息和对应口味信息 65
4.4修改菜品---代码开发---测试数据回显 66
一、文件上传下载 50
1.1文件上传 50
服务端如何接收客户端上传的文件:
1.2文件下载
注:本质上是流的操作处理
1.3文件上传下载---文件上传代码实现1
代码部分:
@Slf4j
@RestController
@RequestMapping("/common")
public class CommonController {
/**
* 文件上传
* @param file
* @return
*/
@PostMapping("/upload")
public R<String> upload(MultipartFilte file){//file:参数名要与页面请求的文件名一致
//file是一个临时文件,需要转存到指定位置,否则本次请求完成后临时文件会删除
log.info(file.toString());
return null;
}
1.4文件上传下载---文件上传代码实现2
文件上传的完善:代码如下(主要实现功能1、指定路径的保存,2、照片文件名的随机命名)
@Slf4j
@RestController
@RequestMapping("/common")
public class CommonController {
@Value("${reggie.path}")
private String basePath;
/**
* 文件上传
* @param file
* @return
*/
@PostMapping("/upload")
public R<String> upload(MultipartFile file){//file:参数名要与页面请求的文件名一致
//file是一个临时文件,需要转存到指定位置,否则本次请求完成后临时文件会删除
log.info(file.toString());
//原始文件名
String originalFilename = file.getOriginalFilename();//例如原始的文件名:abc.jpg
//解决原始文件名的后缀
String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));//获取得到 .jpg
//判断路径是否存在
//创建一个目录对象
File dir = new File(basePath);
//判断当前目录是否存在
if(!dir.exists()){
//目录不存在,需要创建
dir.mkdirs();
}
//使用UUID重新生成文件名,放置文件名重复造成文件覆盖
String fileName = UUID.randomUUID().toString() + suffix;//重新随机的给文件名命名 dfjshgnk.jpg
try {
//将临时文件转存到指定的位置
file.transferTo(new File(basePath + fileName));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
1.5文件上传下载---文件下载代码实现 53
二、新增菜品 54
2.1需求分析 54
2.2数据模型
2.3新增菜品---代码开发---准备工作&梳理交互过程 55
梳理交互过程:
2.4新增菜品---代码开发---查询分类数据 56
本部分主要是实现以下功能,点击新增菜品处的菜品分类会自动回显菜品的分类选择。
本部分代码:还是在catagorycontroller中服务层controller中进行修改。
/**
* 根据条件查询分类数据
* @param category
* @return
*/
@GetMapping("/list")
public R<List<Category>> list(Category category){
//条件构造器
LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
//添加条件
queryWrapper.eq(category.getType() != null,Category::getType,category.getType());
//添加排序条件
queryWrapper.orderByAsc(Category::getType).orderByAsc(Category::getUpdateTime);
List<Category> list = categoryService.list(queryWrapper);
return R.success(list);
}
2.5新增菜品---代码开发---接收页面提交的数据 57
由于本部分提交的数据,在原来的实体类中有一些属性数据不存在,导入了一个新的创建的类,用于封装页面提交的数据。
注:该类的作用:用于展示层于服务层之间数据的交互
步骤一:添加新的数据交互类
步骤二:在controller层进行方法的书写驱动
/**
* 菜品管理
*/
@Slf4j
@RestController
@RequestMapping("/dish")
public class DishController {
@Autowired
private DishService dishService;
@Autowired
private DishFlavorService dishFlavorService;
/**
* 新增菜品
* @param dishDto
* @return
*/
@PatchMapping
public R<String> save(@RequestBody DishDto dishDto){//Dish这个类是一个新的封装controller层与展现层数据交互的类,
// 由于本部分涉及到两个json,所以采用该类做封装
log.info(dishDto.toString());
return null;
}
}
2.6新增菜品---代码开发---保存数据到菜品表和菜品口味表(操作多张表的处理) 58
由于存在对数据库中的多张表的处理,需要事务控制,需要开启事务AOP功能。添加注解@Transactional。并且需要在启动类中添加,开启启动类的注@EnableTransactionManagement
代码部分:
@Slf4j
@Service
//public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
public class DishServiceImpl extends ServiceImpl<DishMapper,Dish> implements DishService {
@Autowired
private DishFlavorService dishFlavorService;
//新增菜品,同时保存对应的口味数据
/**
* 新增菜品,同时保存对应的口味数据
* @param dishDto
*/
@Transactional
public void saveWithFlavor(DishDto dishDto) {
//保存菜品的基本信息到菜品表dish
this.save(dishDto);
Long dishId = dishDto.getId();//获取目前正在保存的菜品的id
//菜品口味
List<DishFlavor> flavors = dishDto.getFlavors();
flavors = flavors.stream().map((item) ->{ //将每个元素都重新赋了一个新的名称,并保存到集合当中
item.setDishId(dishId);
return item;
}).collect(Collectors.toList());
// //保存菜品口味数据到菜品口味表dish_flavor
// dishFlavorService.saveBatch(dishDto.getFlavors());
}
}
并且在启动类处添加启动事务开启的注解@EnableTransactionManagement
2.7新增菜品---代码开发---功能测试 59
三、菜品信息分页查询 60
3.1需求分析 60
3.2代码开发---梳理交互过程 61
发布的请求是三部分的数据信息参数:
本部分是实现的效果:
本部分实现代码:
/**
* 菜品信息的分页
* @param page
* @param pageSize
* @param name
* @return
*/
@GetMapping("/page")
public R<Page> page(int page,int pageSize, String name){
//构造分页构造对象
Page<Dish> pageInfo = new Page<>(page,pageSize);
//条件构造器
LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
//添加过滤条件
queryWrapper.like(name != null,Dish::getName,name);
//添加排序条件
queryWrapper.orderByDesc(Dish::getUpdateTime);
//执行分页查询
dishService.page(pageInfo,queryWrapper);
return R.success(pageInfo);
}
3.3菜品信息分页查询---代码开发2(菜品分类的完善)62
由于返回的值是菜品分类的id,并不是分类的结果。所以不显示。本部分采用之前创建的DishDto
本部分代码:
/**
* 菜品信息的分页
* @param page
* @param pageSize
* @param name
* @return
*/
@GetMapping("/page")
public R<Page> page(int page,int pageSize, String name){
//构造分页构造对象
Page<Dish> pageInfo = new Page<>(page,pageSize);
Page<DishDto> dishDtoPage = new Page<>();
//条件构造器
LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
//添加过滤条件
queryWrapper.like(name != null,Dish::getName,name);
//添加排序条件
queryWrapper.orderByDesc(Dish::getUpdateTime);
//执行分页查询
dishService.page(pageInfo,queryWrapper);
//对象拷贝
BeanUtils.copyProperties(pageInfo,dishDtoPage,"records");
List<Dish> records = pageInfo.getRecords();
List<DishDto> list = records.stream().map((item) ->{
DishDto dishDto = new DishDto();
Long categoryId = item.getCategoryId();//分类id
//根据id查询分类对象
Category category = categoryService.getById(categoryId);
String categoryName = category.getName();
dishDto.setCategoryName(categoryName);
return dishDto;
}).collect(Collectors.toList());
dishDtoPage.setRecords(list);
return R.success(dishDtoPage);
}
3.5菜品信息分页查询---功能测试 63
四、修改菜品 64
4.1需求分析 64
4.2代码开发---梳理交互过程 64
注:
1、新增菜品和修改菜品信息使用的是同一个前端的界面
2、处理上面的四次请求
4.3修改菜品---代码开发---根据id查询菜品信息和对应口味信息 65
如何匹配id在url中:
如图所示:
代码的解决:使用注解@PathVariable