菜品分类下拉列表
CategoryController里面写
/**
* 根据条件查询分类数据
*
* @param category
* @return
*/
@GetMapping("/list")
@ApiOperation("菜品分类目录")
public R<List<Category>> list(Category category) {
List<Category> list = categoryService.list(Wrappers.lambdaQuery(Category.class)
//type=1,前端传过来的,就是查询类型为1的,1就是菜品不是套餐,2是套餐
.eq(category.getType() != null, Category::getType, category.getType())
.orderByDesc(Category::getUpdateTime)
);
return R.success(list);
}
保存菜品时要保存口味要操作两张表
我们可以看到在保存菜品时,页面传递过来的是json格式数据,格式如下:
{
"name":"佛跳墙",
"price":88800,
"code":"",
"image":"da9e1c70-fc32-4781-9510-a1c4ccd2ff59.jpg",
"description":"佛跳墙",
"status":1,
"categoryId":"1397844357980663809",
"flavors":[
{
"name":"辣度",
"value":"[\"不辣\",\"微辣\",\"中辣\",\"重辣\"]",
"showOption":false
},
{
"name":"忌口",
"value":"[\"不要葱\",\"不要蒜\",\"不要香菜\",\"不要辣\"]",
"showOption":false
}
]
}
在服务端我们应该如何来封装前端传递的数据呢,我们发现,如果使用菜品类Dish来封装,只能封装菜品的基本属性,flavors属性是无法封装的。那么这个时候,我们应该如何处理呢?
这个时候,我们需要自定义一个实体类,然后继承自 Dish,并对Dish的属性进行拓展,增加 flavors 集合属性(内部封装DishFlavor)。清楚了这一点之后,接下来就进行功能开发。
导入 DishDto 实体类
封装页面传递的请求参数。
所属包: com.itheima.reggie.dto
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;
}
拓展: 我们在做项目时,经常会涉及到各种类型的实体模型。基本包含以下几种
DTO | Data Transfer Object(数据传输对象),一般用于展示层与服务层之间的数据传输。 |
VO | Value Object(值对象), 主要用于封装前端页面展示的数据对象,用一个VO对象来封装整个页面展示所需要的对象数据 |
PO | Persistant Object(持久层对象), 是ORM(Objevt Relational Mapping)框架中Entity,PO属性和数据库中表的字段形成一一对应关系 |
新增菜品
DishController
private final DishService dishService;
/**
* 新增菜品
*
* @param dishDto
* @return
*/
@ApiOperation("新增菜品")
@PostMapping
public R<String> save(@RequestBody DishDto dishDto) {
log.info(dishDto.toString());
dishService.saveWithFlavor(dishDto);
return R.success("新增菜品成功");
}
DishService
//新增菜品,同时插入菜品对应的口味数据,需要操作两张表:dish、dish_flavor
void saveWithFlavor(DishDto dishDto);
DishServiceImpl
private final DishFlavorService dishFlavorService;
/**
* 新增菜品,同时保存对应的口味数据
*/
@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(flavors);
}
说明:
由于在 saveWithFlavor 方法中,进行了两次数据库的保存操作,操作了两张表,那么为了保证数据的一致性,我们需要在方法上加上注解 @Transactional来控制事务。
在引导类上加注解 @EnableTransactionManagement
Service层方法上加的注解@Transactional要想生效,需要在引导类上加上注解 @EnableTransactionManagement, 开启对事务的支持。
package com.itheima.reggie;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import java.net.InetAddress;
@Slf4j
@SpringBootApplication
@ServletComponentScan
@EnableTransactionManagement
public class ReggieApplication {
public static void main(String[] args) {
ConfigurableApplicationContext application = SpringApplication.run(ReggieApplication.class, args);
Environment env = application.getEnvironment();
String port = env.getProperty("server.port");
log.info("\n----------------------------------------------------------\n\t" +
"running success! Access URLs:\n\t" +
"Local: \t\thttp://localhost:" + port +"/backend/page/login/login.html"+"\n\t" +
"Swagger文档: \thttp://localhost:" + port + "/doc.html\n" +
"----------------------------------------------------------");
}
}