当前位置:网站首页>5. dish management business development
5. dish management business development
2022-06-24 10:16:00 【xjhqre】
Dish management business development
1、 File upload function
1.1、 Import page
Import from data upload.html file

1.2、 Write the file upload method
1、 Save address configuration , stay application.yml Add the following configuration
reggie:
path: D:\reggieImg\
2、 Implementation method
package com.itheima.reggie.controller;
import com.itheima.reggie.common.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
/** * @Author: xjhqre * @DateTime: 2022/6/18 16:18 */
@RestController
@RequestMapping("/common")
@Slf4j
public class CommonController {
@Value("${reggie.path}")
private String basePath;
@PostMapping("/upload")
public R<String> upload(MultipartFile file) {
// file It's a temporary document , It needs to be transferred to the specified location , Otherwise, the temporary file will be deleted after this request is completed
log.info(file.toString());
// Original filename
String originalFilename = file.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
// Use UUID Regenerate file name , Prevent file names from being overwritten repeatedly
String fileName = UUID.randomUUID() + suffix;
// Create a directory object
File dir = new File(basePath);
// Determine whether the current directory exists
if (!dir.exists()) {
dir.mkdirs();
}
try {
// Transfer the temporary file to the specified location
file.transferTo(new File(basePath + fileName));
} catch (IOException e) {
e.printStackTrace();
}
return R.success(fileName);
}
}
1.3、 Open upload picture request address
modify LoginCheckFilter Filter configuration for

1.4、 Test image upload function
Access address http://localhost:8080/backend/page/demo/upload.html
Test upload function
1.5、 Use alicloud OSS Storage ( Optional )
1.5.1、 establish bucket

1.5.2、 establish AccessKey
1、 Use child users AccessKey, Remember to save after creation accessKeySecret, Unable to query in the future

2、 Add user rights

1.5.3、 Introduce dependencies
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
1.5.4、 Create upload method
/** * Upload files OSS * @param file * @return */
@PostMapping("/upload")
public R<String> upload(MultipartFile file) {
// file It's a temporary document , It needs to be transferred to the specified location , Otherwise, the temporary file will be deleted after this request is completed
log.info(file.toString());
// Original filename
String originalFilename = file.getOriginalFilename();
String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
// Endpoint East China 1( Hangzhou ) For example , Other Region Please fill in according to the actual situation .
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// Alicloud account AccessKey Have all the API Access rights of , The risk is high . It is highly recommended that you create and use it RAM The user carries out API Visit or daily operations , Please log in RAM Console creation RAM user .
String accessKeyId = " Yours accessKeyId";
String accessKeySecret = " Yours accessKeySecret";
// Fill in Bucket name , for example examplebucket.
String bucketName = " Yours bucketName";
// Fill in Object The full path , The full path cannot contain Bucket name , for example exampledir/exampleobject.txt.
String objectName = UUID.randomUUID() + suffix;
// establish OSSClient example .
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
// getInputStream() Return to one InputStream To read the contents of the file . Through this method, you can get the stream
InputStream multipartFileInputStream = null;
try {
multipartFileInputStream = file.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
try {
// establish PutObject request .
ossClient.putObject(bucketName, objectName, multipartFileInputStream);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
return R.success(objectName);
}
2、 File download function
demand : When we upload an image, we need to echo it in the browser
2.1 Write the download method
stay CommonController Write below download Method
/** * File download * @param name * @param response */
@GetMapping("/download")
public void download(String name, HttpServletResponse response) {
try {
// Input stream , Read picture information from local disk
FileInputStream fileInputStream = new FileInputStream(new File(basePath + name));
// Output stream , Output picture information to browser
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();
}
// close resource
outputStream.close();
fileInputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
2.2、 Test the picture echo function
2.3、 request OSS picture ( Optional )
If used OSS Upload picture service , Want to get OSS picture , Just modify the request path of the picture , As shown in the figure below :
modify upload.html In the file handleAvatarSuccess Method request path

3、 New dishes
Execute the process :
- page (backend/page/food/add.html) send out ajax request , Request the server to obtain the dish classification data and display it in the drop-down box
- The page sends a request for image upload , Request the server to save the picture to the server
- The page sends a request for image download , Echo the uploaded picture
- Click the save button , send out ajax request , Take the relevant data of dishes as json Submit to the server in the form of
3.1、 preparation
First, prepare the required classes and interfaces :
- Entity class DishFlavor( Import from data )
- Mapper Interface DishFlavorMapper
- Business layer interface DishFlavorService
- Business layer implementation classes DishFlavorServiceImpl
- Control layer DishController
Dish and DishFlavor Our business is conducted by DishController Handle
3.2、 Query the menu classification list
stay CategoryController Written in list Method
/** * Query classified data according to conditions * @param category * @return */
@GetMapping("/list")
public R<List<Category>> list(Category category) {
// Conditional constructor
LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<>();
// Adding conditions
queryWrapper.eq(category.getType() != null, Category::getType, category.getType());
// Add sorting criteria
queryWrapper.orderByAsc(Category::getSort).orderByDesc(Category::getUpdateTime);
List<Category> list = categoryService.list(queryWrapper);
return R.success(list);
}
3.3、 Import DTO
Because of the data from the front end , On the back end, you can't directly use Dish and DishFlavor receive , You need an entity class that also has Dish and DishFlavor Properties of .
package com.itheima.reggie.dto;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class DishDto extends Dish {
private List<DishFlavor> flavors = new ArrayList<>();
private String categoryName;
private Integer copies;
}
It can be seen that a subclass can inherit everything from the parent class . You just can't get permission directly private or default Properties and methods of
3.4、 establish controller Method
stay DishController Class save Method
package com.itheima.reggie.controller;
import com.itheima.reggie.common.R;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@Slf4j
@RestController
@RequestMapping("/dish")
public class DishController {
@Autowired
DishService dishService;
@Autowired
DishFlavorService dishFlavorService;
/** * New dishes * @param dishDto * @return */
@PostMapping
public R<String> save(@RequestBody DishDto dishDto) {
log.info(dishDto.toString());
dishService.saveWithFlavor(dishDto);
return R.success(" Added dishes successfully ");
}
}
3.5、 stay service Method defined in
stay DishService In the definition of saveWithFalvor Method
package com.itheima.reggie.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Dish;
public interface DishService extends IService<Dish> {
// New dishes , At the same time, insert the taste data corresponding to the dish , You need to operate two tables :dish and dish_falvor
void saveWithFalvor(DishDto dishDto);
}
3.6、 stay ServiceImpl Middle implementation method
package com.itheima.reggie.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.itheima.reggie.dto.DishDto;
import com.itheima.reggie.entity.Category;
import com.itheima.reggie.entity.Dish;
import com.itheima.reggie.entity.DishFlavor;
import com.itheima.reggie.mapper.CategoryMapper;
import com.itheima.reggie.mapper.DishMapper;
import com.itheima.reggie.service.CategoryService;
import com.itheima.reggie.service.DishFlavorService;
import com.itheima.reggie.service.DishService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
@Service
public class DishServiceImpl extends ServiceImpl<DishMapper, Dish> implements DishService {
@Autowired
private DishFlavorService dishFlavorService;
/** * New dishes , At the same time, save the corresponding taste data * @param dishDto */
@Override
@Transactional
public void saveWithFlavor(DishDto dishDto) {
// Save the basic information of the dishes to dish surface
this.save(dishDto);
Long dishId = dishDto.getId();
// Dish taste
List<DishFlavor> flavors = dishDto.getFlavors();
flavors = flavors.stream().peek(item -> item.setDishId(dishId)).collect(Collectors.toList());
// Save the dish taste data to dish_flavor surface
dishFlavorService.saveBatch(flavors);
}
}
3.7、 Start the transaction in the main startup class
add to @EnableTransactionManagement annotation
@Slf4j
@SpringBootApplication
@ServletComponentScan
@EnableTransactionManagement
public class ReggieApplication {
public static void main(String[] args) {
SpringApplication.run(ReggieApplication.class, args);
log.info(" The project started successfully ...");
}
}
3.8、 Test new dishes
After adding dishes, check whether the database is added correctly

4、 Pagination query of dish information
4.1、 Create a paging query method
4.1.1、 Method 1 : The teacher's method
/** * Pagination query of dish information * @param page * @param pageSize * @param name * @return */
@GetMapping("/page")
public R<Page<DishDto>> page(int page, int pageSize, String name) {
// Constructing a page builder object
Page<Dish> pageInfo = new Page<>(page, pageSize);
Page<DishDto> dishDtoPage = new Page<>();
// Conditional constructor
LambdaQueryWrapper<Dish> queryWrapper = new LambdaQueryWrapper<>();
// Add filter conditions
queryWrapper.like(name != null, Dish::getName, name);
// Add sorting criteria
queryWrapper.orderByDesc(Dish::getUpdateTime);
// Perform paging queries
dishService.page(pageInfo, queryWrapper);
// Object Copy
BeanUtils.copyProperties(pageInfo, dishDtoPage, "records");
List<Dish> records = pageInfo.getRecords();
List<DishDto> list = records.stream().map(item -> {
DishDto dishDto = new DishDto();
BeanUtils.copyProperties(item, dishDto);
Long categoryId = item.getCategoryId();
// According to the classification id Query classification objects
Category category = categoryService.getById(categoryId);
if (category != null) {
String categoryName = category.getName();
dishDto.setCategoryName(categoryName);
}
return dishDto;
}).collect(Collectors.toList());
dishDtoPage.setRecords(list);
return R.success(dishDtoPage);
}
4.1.2、 Method 2 : Join table query method ( Optional )
1、DishController layer
/** * Pagination query of dish information * @param page * @param pageSize * @param name * @return */
@GetMapping("/page")
public R<Page<DishDto>> page(int page, int pageSize, String name) {
// Constructing a page builder object
Page<DishDto> pageInfo = new Page<>(page, pageSize);
dishService.selectDishWithCategoryNameList(pageInfo, name);
return R.success(pageInfo);
}
2、DishService layer , Add the following method declaration
// Query the information of all dishes with category names
void selectDishWithCategoryNameList(Page<DishDto> page, String name);
3、DishServiceImpl layer , Realization selectDishWithCategoryNameList Method
/** * Query all Dish With the category name of the dishes * @param page */
@Override
public void selectDishWithCategoryNameList(Page<DishDto> page, String name) {
List<DishDto> records = baseMapper.selectDishWithCategoryNameList(page, name == null ? "" : name);
page.setRecords(records);
}
4、DishMapper layer , Add the following method declaration
@Select("SELECT a.*, b.`name` AS category_name FROM dish a JOIN category b ON a.`category_id` = b.`id` WHERE a.`name` LIKE CONCAT('%',#{name},'%') ORDER BY sort")
List<DishDto> selectDishWithCategoryNameList(Page<DishDto> page, @Param("name") String name);
4.2、 The menu shows Alibaba cloud OSS picture ( Optional )
If you use images stored by Alibaba cloud , Need modification backend/page/food/list.html There are two places in the document
modify :preview-src-list Value

modify return Value

4.3、 Test the effect of dish query

5、 Modify the menu page data echo
Execute the process :
- Page sending ajax request , Request the server to obtain classification data , It is used to display the data in the drop-down box of dish classification
- Page sending ajax request , Request server , according to id Query the current dish information , Used for echo of dish information
- Page send request , Request the server to download pictures , Used for page picture echo
- Click the save button , Page sending ajax request , Use the modified dish related data as json Submit to the server in the form of
5.1、DishController
establish get Method
/** * according to id Query the dish information and the corresponding taste information * @param id * @return */
@GetMapping("/{id}")
public R<DishDto> get(@PathVariable Long id) {
DishDto dishDto = dishService.getByIdWithFlavor(id);
return R.success(dishDto);
}
5.2、DishService
Statement getByIdWithFlavor Method
// according to id Query the dish information and the corresponding taste information
DishDto getByIdWithFlavor(Long id);
5.3、DishServiceImpl
Realization getByIdWithFlavor Method
/** * according to id Query the dish information and the corresponding taste information * @param id * @return */
@Override
public DishDto getByIdWithFlavor(Long id) {
// Query the basic information of dishes , from dish Table query
Dish dish = this.getById(id);
DishDto dishDto = new DishDto();
BeanUtils.copyProperties(dish, dishDto);
// Query the taste information corresponding to the current dish , from dish_flavor Table query
LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DishFlavor::getDishId, dish.getId());
List<DishFlavor> flavors = dishFlavorService.list(queryWrapper);
dishDto.setFlavors(flavors);
return dishDto;
}
5.4、 Alibaba cloud OSS Picture echo ( Optional )
modify backend/page/food/add.html file

5.5、 Test modification echo

6、 Modify the dishes
Delete first dish All corresponding dish_flavor, Adding
6.1、DishController
/** * Modify the dishes * @param dishDto * @return */
@PutMapping
public R<String> update(@RequestBody DishDto dishDto) {
log.info(dishDto.toString());
dishService.updateWithFlavor(dishDto);
return R.success(" Dishes modified successfully ");
}
6.2、DishService
// Update dish information , At the same time, update the corresponding taste information
void updateWithFlavor(DishDto dishDto);
6.3、DishServiceImpl
@Override
@Transactional
public void updateWithFlavor(DishDto dishDto) {
// to update dish Table basic information
this.updateById(dishDto);
// Clear the taste data corresponding to the current dish
LambdaQueryWrapper<DishFlavor> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(DishFlavor::getDishId, dishDto.getId());
dishFlavorService.remove(queryWrapper);
// Add the currently submitted taste data
List<DishFlavor> flavors = dishDto.getFlavors();
flavors = flavors.stream().peek(item -> item.setDishId(dishDto.getId())).collect(Collectors.toList());
dishFlavorService.saveBatch(flavors);
}
6.4、 Test and modify dishes
7、 Delete and batch delete dishes ( Optional )
Use logical deletion
First delete the taste corresponding to the dish , Deleting dishes ,is_delete by 1 Said to delete ,0 Indicates not deleted
7.1、 modify Dish and DishFlavor Entity class
to isDeleted Property to add comments @TableLogic(value = "0", delval = "1"). After adding this comment , call mybatis-plus The deletion method of is actually update Method

7.2、DishController
/** * Logical deletion * @param ids * @return */
@DeleteMapping
@Transactional
public R<String> delete(Long[] ids) {
log.info(" Batch deleted id:{}", Arrays.toString(ids));
// First, delete the taste information corresponding to the dishes
dishFlavorService.removeByDishIds(Arrays.asList(ids));
// Delete the dishes logically
dishService.removeByIds(Arrays.asList(ids));
return R.success(" Delete dishes successfully ");
}
7.3、DishFlavorService
/** * Delete the taste record of the corresponding dish logically * @param dishIds */
void removeByDishIds(List<Long> dishIds);
7.4、DishFlavorServiceImpl
@Service
public class DishFlavorServiceImpl extends ServiceImpl<DishFlavorMapper, DishFlavor> implements DishFlavorService {
@Autowired
DishFlavorMapper dishFlavorMapper;
/** * Delete the taste record of the corresponding dish logically * @param dishIds */
@Override
public void removeByDishIds(List<Long> dishIds) {
dishFlavorMapper.removeByDishIds(dishIds);
}
}
7.5、DishFlavorMapper
@Mapper
public interface DishFlavorMapper extends BaseMapper<DishFlavor> {
void removeByDishIds(@Param("dishIds") List<Long> dishIds);
}
7.6、DishFlavorDao.xml
stay resources Create under directory mapper Catalog , stay mapper Create under directory DishFlavorDao.xml.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.reggie.mapper.DishFlavorMapper">
<update id="removeByDishIds">
UPDATE dish_flavor SET is_deleted=1 WHERE dish_id IN
<foreach collection="dishIds" item="id" index="index" open="(" close=")" separator=",">
#{id}
</foreach>
AND is_deleted=0
</update> <!-- modify -->
</mapper>
7.7、 Modify the menu paging query function
Because we use logical deletion , Deleted dishes can still be seen on the menu , We need to modify the paging query function
The following is to modify the paging query method I wrote , If you use the teacher's paging query method, please modify it by yourself
modify DishMapper Inside selectDishWithCategoryNameList Method , Add... To the notes is_deleted The field can be judged
@Select("SELECT a.*, b.`name` AS category_name FROM dish a JOIN category b ON a.`category_id` = b.`id` WHERE a.`name` LIKE CONCAT('%',#{name},'%') AND a.`is_deleted` = 0 ORDER BY sort")
List<DishDto> selectDishWithCategoryNameList(Page<DishDto> page, @Param("name") String name);
7.8、 Test batch delete
8、 Start and stop selling in batches ( Optional )
8.1、DishController
/** * Stop selling and start selling in batches * @param status * @param ids * @return */
@PostMapping("status/{status}")
@Transactional
public R<String> status(@PathVariable("status") int status, @RequestParam Long[] ids) {
log.info(" Start and stop selling in batches :{},{}", status, Arrays.toString(ids));
dishService.updateStatusByIds(status, ids);
return R.success(" Successful start and stop of batch sales ");
}
8.2、DishService
// Start and stop selling in batches
void updateStatusByIds(int status, Long[] ids);
8.3、DishServiceImpl
/** * Start and stop selling in batches * @param status * @param ids */
@Override
public void updateStatusByIds(int status, Long[] ids) {
dishMapper.updateStatusByIds(status, ids);
}
8.4、DishMapper
void updateStatusByIds(@Param("status") int status, @Param("ids") Long[] ids);
8.5、DishDao.xml
stay resources In the catalog mapper Create under directory DishDao.xml file
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.reggie.mapper.DishMapper">
<update id="updateStatusByIds">
UPDATE dish
SET status = #{status}
WHERE id IN
<foreach collection="ids" item="id" index="index" open="(" close=")" separator=",">
#{id}
</foreach>
AND status != #{status}
</update> <!-- modify -->
</mapper>
8.6、 Test the start and stop of batch sales
边栏推荐
- 大中型企业如何构建自己的监控体系
- Basic operations on binary tree
- 一群骷髅在飞canvas动画js特效
- SSM整合
- Array seamless scrolling demo
- Juul, the American e-cigarette giant, suffered a disaster, and all products were forced off the shelves
- 414-二叉树的递归遍历
- El table Click to add row style
- Which of the top ten securities companies has the lowest Commission and is the safest and most reliable? Do you know anything
- Getting user information for applet learning (getuserprofile and getUserInfo)
猜你喜欢

简单的价格表样式代码

Canvas draw picture

How to manage massive network infrastructure?

leetCode-2221: 数组的三角和

TP5 using post to receive array data times variable type error: solution to array error

Yolov6: the fast and accurate target detection framework is open source

Top issue tpami 2022! Behavior recognition based on different data modes: a recent review

Cicflowmeter source code analysis and modification to meet requirements

线程池的状态

Cookie encryption 4 RPC method determines cookie encryption
随机推荐
植物生长h5动画js特效
美国电子烟巨头 Juul 遭遇灭顶之灾,所有产品强制下架
学习使用php实现无限极评论和无限极转二级评论解决方案
CVPR 2022 oral | NVIDIA proposes an efficient visual transformer network a-vit with adaptive token. The calculation of unimportant tokens can be stopped in advance
微信小程序学习之 实现列表渲染和条件渲染.
PostgreSQL DBA quick start - source compilation and installation
分布式 | 如何与 DBLE 进行“秘密通话”
El table Click to add row style
利用pandas读取SQL Sever数据表
静态链接库和动态链接库的区别
小程序学习之获取用户信息(getUserProfile and getUserInfo)
Observer mode
NVIDIA's CVPR 2022 oral is on fire! 2D images become realistic 3D objects in seconds! Here comes the virtual jazz band!
2022-06-23: given a nonnegative array, select any number to make the maximum cumulative sum a multiple of 7, and return the maximum cumulative sum. N is larger, to the 5th power of 10. From meituan. 3
PHP uses recursive and non recursive methods to create multi-level folders
Array seamless scrolling demo
Arbre binaire partie 1
leetCode-面试题 01.05: 一次编辑
SQL Server AVG function rounding
微信小程序rich-text图片宽高自适应的方法介绍(rich-text富文本)