新增套餐
需要添加名称,价格,菜品(其中菜品需要选择所以需要根据分类id来回显所有的菜品提供选择),上传图片(之前已经完成)
根据分类id回显
明显是GETMETHOD,参数就是Long categoryId,
返回的是List用于前端回显,
其中,
serivce (categoryId,返回的是List)
public List<Dish> getDishByGategoryId(Long categoryId){
Dish dish = Dish.builder()
.categoryId(categoryId)
.status(StatusConstant.ENABLE)
.build();
List<Dish> dishes = dishMapper.getByCateGroyId(dish);
return dishes;
}
为什么这里参数是Dish而不是categoryId呢?
??????????
因为需要在售的吗?那我为什么不能在售直接搜索呢?
Mapper ( 参数是dish,因为回显的时候可以让管理员搜索name)
<select id="getByCateGroyId" resultType="com.sky.entity.Dish" parameterType="com.sky.entity.Dish">
select * from dish
<where>
<if test="name != null">
and name like concat('%',#{name},'%')
</if>
<if test="categoryId != null">
and category_id = #{categoryId}
</if>
<if test="status != null">
and status = #{status}
</if>
</where>
order by create_time desc
</select>
为什么这里参数是Dish而不是categoryId呢?
??????????
补档:是因为在选择将dish添加进套餐的时候,可以让管理员搜索name,或者设置在售的dish再进行添加
是一个动态sql的过程。
套餐分页查询
controller (接受分页pageQueryDTO返回pageResult)
接受分页setmealpagequertDTO
返回一个PageResult类型
@GetMapping("/page")
@ApiOperation("套餐分页查询")
public Result<PageResult> page(SetmealPageQueryDTO setmealPageQueryDTO){
log.info("套餐分页查询:{}",setmealPageQueryDTO);
PageResult pageResult = setmealService.pageQuery(setmealPageQueryDTO);
return Result.success(pageResult);
}
serivice (返回的是Page(数量,List))
public PageResult pageQuery(SetmealPageQueryDTO setmealPageQueryDTO){
PageHelper.startPage(setmealPageQueryDTO.getPage(),setmealPageQueryDTO.getPageSize());
Page<SetmealVO> page = setmealMapper.pageQuery(setmealPageQueryDTO);
long total = page.getTotal();
List<SetmealVO> result = page.getResult();
return new PageResult(total,result);
}
使用pageHelper开始形成page,
Mapper参数查询DTO返回Page参数,
return 返回给controller的是前面说的PageResult 对象参数为total和List
Mapper重头戏
<select id="pageQuery" resultType="com.sky.vo.SetmealVO">
select
s.*,c.name categoryName
from
setmeal s
left join
category c
on
s.category_id = c.id
<where>
<if test="name != null">
and s.name like concat('%',#{name},'%')
</if>
<if test="status != null">
and s.status = #{status}
</if>
<if test="categoryId != null">
and s.category_id = #{categoryId}
</if>
</where>
order by s.create_time desc
</select>
查询套餐VO的所有数据
建议回看一下口味id那一部分的写法
删除套餐
确定套餐是否在售,否则不能删除
controller (@RequestParam接收参数)
需要从@RequestParam接受ids的参数,又忘了
@DeleteMapping
@ApiOperation("删除套餐")
public Result delete(@RequestParam List<Long> ids){
log.info("删除ids的套餐");
setmealService.deleteByIds(ids);
return Result.success();
}
service ( @Transactional注释)
@Transactional
public void deleteByIds(List<Long> ids){
//检查是否在套餐之中
for(Long id:ids){
Setmeal byId = setmealMapper.getById(id);
if(StatusConstant.ENABLE == byId.getStatus()){
throw new DeletionNotAllowedException(MessageConstant.SETMEAL_ON_SALE);
}
}
需要从setmeal和setmealDish表中都删除
//需要从setmeal和setmealDish表中都删除
ids.forEach(setmealId->{
setmealMapper.deleteBatch(setmealId);
setmealDishMapper.deleteBatch(setmealId);
});
}
- Service层方法:通常,我们在Service层的方法上使用@Transactional注解,因为Service层负责业务逻辑,这些逻辑通常涉及多个DAO操作。将这些操作放在一个事务中,可以确保它们要么全部成功,要么全部回滚。
- 需要确保数据一致性的操作:任何需要确保数据一致性的操作都应该放在事务中。例如,转账操作必须确保从一个账户扣款的同时向另一个账户加款。
- 需要回滚的操作:如果在操作过程中可能会抛出异常,并且需要在异常发生时回滚操作,那么这些操作应该放在事务中。
Mapper
普通delete
直接在setmeal和setmeal_dish 中和setmealId相关的全部删除
修改套餐
controller(回显需要Path变量{id}返回VO回显 加 修改需要Body的DTO)
@GetMapping("/{id}")
@ApiOperation("根据id查询套餐")
public Result<SetmealVO> getById(@PathVariable Long id) {
SetmealVO setmealVO = setmealService.getByIdWithDish(id);
return Result.success(setmealVO);
}
@PutMapping
@ApiOperation("修改套餐")
public Result update(@RequestBody SetmealDTO setmealDTO) {
setmealService.update(setmealDTO);
return Result.success();
}
Service (回显需要SetmealDTO和所有的Dishes 和 修改需要删除所有的setmeal_dish 再重新插入 记得transaction注释)
从setmeal_dish中增加所有的dishes内容,set到VO中返回
public SetmealVO getByIdWithDish(Long id){
//查询setmeal的所有信息,还需要在setmeal里面搜索dish内容然后再给回显出来
//先获取setmeal的id然后再查询所有的dishes
SetmealVO setmealVO = new SetmealVO();
Setmeal setmeal = setmealMapper.getById(id);
List<SetmealDish> dishById = setmealDishMapper.getBySetmealId(id);
BeanUtils.copyProperties(setmeal,setmealVO);
setmealVO.setSetmealDishes(dishById);
return setmealVO;
}
@Transactional
public void update(SetmealDTO setmealDTO) {
Setmeal setmeal = new Setmeal();
BeanUtils.copyProperties(setmealDTO, setmeal);
//1、修改套餐表,执行update
setmealMapper.update(setmeal);
//套餐id
Long setmealId = setmealDTO.getId();
//2、删除套餐和菜品的关联关系,操作setmeal_dish表,执行delete
setmealDishMapper.deleteBySetmealId(setmealId);
List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
setmealDishes.forEach(setmealDish -> {
setmealDish.setSetmealId(setmealId);
});
//3、重新插入套餐和菜品的关联关系,操作setmeal_dish表,执行insert
setmealDishMapper.insertBatch(setmealDishes);
}
Mapper
@Delete("delete from setmeal where id = #{id}")
void deleteBatch(Long ids);
<update id="update">
update setmeal
<set>
<if test="name != null">name = #{name},</if>
<if test="categoryId != null">category_id = #{categoryId},</if>
<if test="price != null">price = #{price},</if>
<if test="image != null">image = #{image},</if>
<if test="description != null">description = #{description},</if>
<if test="status != null">status = #{status},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
<if test="updateUser != null">update_user = #{updateUser},</if>
</set>
where id = #{id}
</update>
@Select("select * from setmeal_dish where setmeal_id = #{setmealId}")
List<SetmealDish> getBySetmealId(Long setmealId);
@Delete("delete from setmeal_dish where setmeal_id = #{setmealId}")
void deleteBySetmealId(Long setmealId);
更改套餐起售状态
controller(Post方法,本质是update需要id来查找其他的内容只更改status)
@PostMapping("/status/{status}")
@ApiOperation("更改起售套餐")
public Result updateStatus(@PathVariable Integer status,Long id){
log.info("更改起售状态:{}",status);
setmealService.updateStatus(status,id);
return Result.success();
}
service(需要查询下面的Dish是否可以起售 然后update整个setmeal)
public void updateStatus(Integer status,Long id){
//需要检查套餐里面的菜品是否都可以销售
//查询setmeal——dish表格中的dish——id
List<Dish> dishes= setmealDishMapper.getDishesBySetmealId(id);
dishes.forEach(dish -> {
if(dish.getStatus() == StatusConstant.DISABLE)
throw new SetmealEnableFailedException(MessageConstant.SETMEAL_ENABLE_FAILED);
});
Setmeal byId = setmealMapper.getById(id);
byId.setStatus(status);
setmealMapper.update(byId);
}
Mapper(查询所有的dish的状态是否可以起售,只知道setmeal的id需要left join连接dish和setmeal_id的表,然后再判断setmeal的id为我们想要查询的那个)
@Select("select a.* from dish a left join setmeal_dish b on a.id = b.dish_id where b.setmeal_id = #{setmealId}")
List<Dish> getDishesBySetmealId(Long id);
mysql 表关系
category
id标识唯一的dish
type标识是菜品分类还是套餐分类 1是菜品 2是套餐
dish
id标识唯一的dish
category_id表示所属的分类 这里的分类是dish分类
dish_flavor
id标识唯一的口味
dish_id标识是哪个菜的
value是字符串数组代表真正的口味 [“无糖”,“少糖”,“半糖”,“多糖”,“全糖”]
setmeal
id标识唯一的setmeal
category_id表示所属的分类 这里的分类是套餐分类
setmeal_dish
id是标识关系
setmeal_id标识属于哪个setmeal
dish_id标识是哪个dish