瑞吉外卖day04

目录

一、实现菜品管理批量删除单个删除

1、问题分析

2、代码实现

二、实现菜品管理批量停/启售

1、问题分析

2、代码实现

三、文件的上传

1、分析

2、代码实现

 3、测试

4、不熟练的技术点

四、文件的下载

1、问题分析

 2、代码实现

3、不熟练的技术点 

3.1异常:

3.2file

 3.3IO

五、新增菜品

1、问题分析

2、代码实现 

2.1回显功能 

2.2新增功能(复习时候特意看一下)

 3、测试

六、实现菜品管理中的分页功能

1、问题分析

2、代码实现

3、测试

4、问题处理(复习重点看)

七、修改菜品

1、需求分析

2、代码实现 

 2.1回显代码

2.2修改代码

 3、测试


一、实现菜品管理批量删除单个删除

1、问题分析

        删除多个时这是前端传过来的信息,可以通过字符串用“,”切割变成一个字符串数组,再把数组内的数据转成Long型存入集合中,这时就可以通过mybatisplus提供的批量删除方法实现批量删除和单个删除了

2、代码实现

    /**
     * 单个删除和批量删除的实现
     * @param ids
     * @return
     */
    @DeleteMapping
    //1397850851245600769,1397851668262465537前端传入的数据
    public R<String> delete( String ids){

        String[] strs= ids.split(",");
        List<Long> id = new ArrayList<>();

        for (String i :strs){
            id.add(Long.parseLong(i));
        }
        dishService.removeByIds(id);
        return R.success("删除成功");
    }
}

测试成功

二、实现菜品管理批量停/启售

1、问题分析

       删除多个时这是前端传过来的信息,可以通过字符串用“,”切割变成一个字符串数组,再把数组遍历把实体类传给mybatisplus的根据id修改方法

2、代码实现

    @PostMapping("/status/{status}")
    public R<String> update(@PathVariable Integer status,String ids){
        String[] id= ids.split(",");
        for(String i: id){
            Dish dish = dishService.getById(i);
            dish.setStatus(status);
            dishService.updateById(dish);
        }
;
        return R.success("菜品修改成功");
    }

测试成功

三、文件的上传

1、分析

2、代码实现

@Slf4j
@RestController
@RequestMapping("/common")
public class CommonController {
//YML中的配置路径
    @Value("${reggie.path}")
    private String basePath;

    //文件上传
    @PostMapping("/upload")
    //MultipartFile file就是文件上传参数,file必须和浏览器发来的name一致
    public R<String> upload(MultipartFile file){

        //file 是一个临时文件,需要转存到指定位置,否则请求完成后临时文件会删除
        log.info("file:{}",file.toString());

        //原始文件名
        String originalFilename = file.getOriginalFilename();
        //截取后缀名
        String suffix =originalFilename.substring(originalFilename.lastIndexOf("."));
        //使用uuid重新生成文件名,防止文件名重复
        String fileName = UUID.randomUUID().toString()+suffix;

        //创建一个目录对象
        File dir = new File(basePath);
        //判断当前目录是否存在
        if(!dir.exists()){
            //目录不存在则创建
            dir.mkdirs();
        }


        try{
            //指定文件位置
            file.transferTo(new File(basePath+fileName));
        }catch (IOException e){
            e.printStackTrace();
         }
        return R.success(fileName);
    }
}

 3、测试

测试成功 

4、不熟练的技术点

1、

2、//指定文件位置
file.transferTo(new File());

 3、在yml配置路径并引用

4、获取原始文件名

file.getOriginalFilename();

 5、生成随机名

UUID.randomUUID()

6、对文件的操作

四、文件的下载

1、问题分析

查看前端页面,文件上传后调用这个方法

可以查到到参数和链接地址name也就是我们文件上传时候的文件名

 2、代码实现

@GetMapping("/download")
    public void download(String name , HttpServletResponse response){

        try{
            //输入流通过输入流读文件
            FileInputStream fileInputStream = new FileInputStream(new File(basePath + name));
            //输出流,通过输出流将文件写回浏览器,在浏览器中显示图片
            ServletOutputStream outputStream = response.getOutputStream();
            response.setContentType("image/jpeg");

            int len =0;
            byte[] bytes =new byte[1024];
            while((len= fileInputStream.read(bytes))!=-1){
                outputStream.write(bytes,0,len);
                outputStream.flush();
            }
        }catch (Exception e){
             e.printStackTrace();
        }




    }

测试成功

3、不熟练的技术点 

对文件的操作,io流。

复习:

3.1异常:

Exception 在开发和调试阶段,都得使用printStackTrace抛出。

finally配合try...catch....使用,不管结果如果最后都会执行funally

try {
            read("a.txt");
        } catch (FileNotFoundException e) {
            //抓取到的是编译期异常  抛出去的是运行期 
            throw new RuntimeException(e);
        } finally {
            System.out.println("不管程序怎样,这里都将会被执行。");
        }

3.2file

1、

  • public File(String pathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
  • public File(String parent, String child) :从父路径名字符串和子路径名字符串创建新的 File实例。

  • public File(File parent, String child) :从父抽象路径名和子路径名字符串创建新的 File实例。

2、

  • public String getAbsolutePath() :返回此File的绝对路径名字符串。

  • public String getPath() :将此File转换为路径名字符串。

  • public String getName() :返回由此File表示的文件或目录的名称。

  • public long length() :返回由此File表示的文件的长度。

3、

  • public boolean exists() :此File表示的文件或目录是否实际存在。

  • public boolean isDirectory() :此File表示的是否为目录。

  • public boolean isFile() :此File表示的是否为文件。

4、

  • public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。

  • public boolean delete() :删除由此File表示的文件或目录。

  • public boolean mkdir() :创建由此File表示的目录。

  • public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录。

5、

  • public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。

  • public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。

 3.3IO

	FileInputStream fis = new FileInputStream("read.txt"); // 文件中为abcde
      	// 定义变量,作为有效个数
        int len ;
        // 定义字节数组,作为装字节数据的容器   
        byte[] b = new byte[2];
        // 循环读取
        while (( len= fis.read(b))!=-1) {
           	// 每次读取后,把数组变成字符串打印
            System.out.println(new String(b));
//输出结果:
//ab
//cd
//ed
            System.out.println(new String(b,0,len));//  len 每次读取的有效字节个数
//输出结果:
//ab
//cd
//e
        }
		// 关闭资源
        fis.close();


五、新增菜品

1、问题分析

需要的表

2、代码实现 

 

2.1回显功能 

    /**
     * 根据条件查询分类数据
     * 这里作用是菜品回显
     * @param category
     * @return
     */
    @GetMapping("/list")
    public R<List<Category>> list(Category category){
        //这里是通过type字段来查询,所以这里只要和tpye对着查询就好了
        //条件构造器
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
        //添加等值查询条件,字符串判断非空StringUtils.isNotEmpty(),基本数据判断非空!=null
        queryWrapper.eq(category.getType()!=null,Category::getType,category.getType());
        //添加排序条件
        queryWrapper.orderByDesc(Category::getSort).orderByDesc(Category::getUpdateTime);
        //
        List<Category> list = categoryService.list(queryWrapper);
        return R.success(list);
    }

测试成功

2.2新增功能(复习时候特意看一下)

这里是同时对两个表进行了接收处理,要怎么实现呢?

通过DTO来对两个表进行封装

@Data
public class DishDto extends Dish {

    private List<DishFlavor> flavors = new ArrayList<>();

    private String categoryName;

    private Integer copies;
}

在DishServiceImpl里声明方法

public interface DishService extends IService<Dish> {
    public void saveWithFlavor(DishDto dishDto);

    
}

在DishServiceImpl进行处理

    @Autowired
    private DishFlavorService dishFlavorService;

    /**
     * 新增菜品,同时保存对应的口味数据
     *
     * @param dishDto
     */
    @Transactional
    //通过dishdto将数据分别保存到两个表中
    public void saveWithFlavor(DishDto dishDto) {
        //保存菜品的基本信息到菜品表dish
        this.save(dishDto);
        //此时我们还未获取到DishFlavors表中的dishId。那么我们可以通过dto中的列表来传入
        //获取到菜品id,这里是dish表中的id
        Long dishId = dishDto.getId();//菜品id

        //菜品口味,将dish表中的id传给flavors表
        List<DishFlavor> flavors = dishDto.getFlavors();
        flavors = flavors.stream().map((item) -> {
            item.setDishId(dishId);
            return item;
            //这里是以列表返回
        }).collect(Collectors.toList());

        //将id和用户输入的数据保存菜品口味数据到菜品口味表dish_flavor
        // saveBatch传列表
        dishFlavorService.saveBatch(flavors);

    }

 多表处理添加事务

DishServiceImpl添加    @Transactional注解

运行类中添加@EnableTransactionManagement注解

在controller层中调用

@PostMapping
    public R<String> save(@RequestBody DishDto dishDto){
        log.info(dishDto.toString());
        dishService.saveWithFlavor(dishDto);
        return R.success("新增菜品成功");
    }

 3、测试

测试成功

六、实现菜品管理中的分页功能

1、问题分析

前面已经问题分析过类似的了这里就不分析了

2、代码实现

    @GetMapping("/page")
    public R<Page> page(int page, int pageSize,String name) {
        //构造分页构造器
        Page pageInfo = new Page(page, pageSize);
        //构造条件构造器
        LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper();
        //通过name查询
        queryWrapper.eq(StringUtils.isNotEmpty(name),Dish::getName,name);
        //添加排序条件查询
        queryWrapper.orderByDesc(Dish::getSort);
        //mybatis-plus自带的分页
        dishService.page(pageInfo, queryWrapper);
        return R.success(pageInfo);

    }

3、测试

测试发现有一个字段并不显示

4、问题处理(复习重点看)

这时候发现少了一个字段为展示,这时候应该如何处理呢?

使用dishdto进行两表的数据关联

在service的实现类中进行数据处理

代码实现:

    @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(源,拷贝到的对象,忽略的字段);records是内容的列表
        //records这里忽略的原因是dishDto中的内容属性和dish中的不同,不能直接拷过去
        BeanUtils.copyProperties(pageInfo,dishDtoPage,"records");
        //把分页中的内容传回给dish列表
        List<Dish> records = pageInfo.getRecords();
        //通过流的形式遍历刚获得的内容,处理完成后用DishDto列表接收
        List<DishDto> list = records.stream().map((item) -> {
            //创建DishDto对象
            DishDto dishDto = new DishDto();
            //将内容先拷贝过去给这个DishDto对象
            BeanUtils.copyProperties(item,dishDto);
            //获取分类id,两表具有的相同字段分类id,可通过分类id来查询数据
            Long categoryId = item.getCategoryId();//分类id
            //根据id查询分类对象
            Category category = categoryService.getById(categoryId);
            //如果不为空通过查询的信息来获取菜品分类,将菜品分类名传给DishDto
            if(category != null){
                String categoryName = category.getName();
                dishDto.setCategoryName(categoryName);
            }
            return dishDto;
            //将内容收集成列表
        }).collect(Collectors.toList());

        dishDtoPage.setRecords(list);

        return R.success(dishDtoPage);
    }

七、修改菜品

1、需求分析

 

回显 

 修改

2、代码实现 

 2.1回显代码

DishService
public  DishDto getByIdWithFlavor(Long id);

DishServiceImpl

    /**
     * 根据id来查询菜品喜喜和口味信息
     * @param id
     * @return
     */
    @Override
    public DishDto getByIdWithFlavor(Long id) {
        //查询菜品基本信息从dish表查询
        Dish dish = this.getById(id);
        DishDto dishDto = new DishDto();

        BeanUtils.copyProperties(dish,dishDto);
        //查询当前菜品对应的口吻信息,从dish_flavor查询
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishFlavor::getDishId,dish.getId());
        List<DishFlavor> flavers = dishFlavorService.list(queryWrapper);
        dishDto.setFlavors(flavers);

        return dishDto;
    }

DishController 

    /**
     * 根据id来查询菜品信息和口吻信息
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public R<DishDto> update(@PathVariable Long id){
        DishDto dishDto = dishService.getByIdWithFlavor(id);
        return R.success(dishDto);
    }

测试成功

2.2修改代码

 Service

    //更新菜品信息,同时更新口味
    public  void updateWithFlavor(DishDto dishDto);

ServiceImpl

    /**
     * 更新菜品信息,同时更新口味
     * @param dishDto
     */
    @Override
    public void updateWithFlavor(DishDto dishDto) {
        //更新dish表的信息
        this.updateById(dishDto);
        //清除口味信息
        LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DishFlavor::getDishId,dishDto.getId());
        dishFlavorService.remove(queryWrapper);
        //添加重新输入的口味信息
        List<DishFlavor> flavors = dishDto.getFlavors();
        flavors=flavors.stream().map((item->{
            item.setDishId(dishDto.getId());
            return item;
        })).collect(Collectors.toList());
        dishFlavorService.saveBatch(flavors);

    }

Controller


    @PutMapping
    public R<String> update(@RequestBody DishDto dishDto){
        log.info(dishDto.toString());

        dishService.updateWithFlavor(dishDto);
        return R.success("菜品修改成功");
    }

 3、测试

测试成功并且功能实现 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值