写给像我一样完完全全的小白的。本人代码水平一塌糊涂,前几天就是机械地跟着视频敲代码。对于Day04的作业本来感觉代码抓瞎一点不会写,尽力去理解业务逻辑后发现好像也没那么难,整体代码可以仿照Day03新增菜品来进行实现!
一、功能一——新增套餐
1. 根据类型type查询分类
目的是根据category表中的type字段来查询当前选择区对应的是“套餐分类”还是“菜品分类”。这个功能在之前已经完成了。但我还是把代码贴过来看下。
(1)代码实现
1) CategoryContorller
/**
* 根据类型查询分类
* @param type
* @return
*/
@GetMapping("/list")
@ApiOperation("根据类型查询分类")
public Result<List<Category>> list(Integer type){
List<Category> list = categoryService.list(type);
return Result.success(list);
}
接下来去CategoryService中声明list方法
2)CategoryService
/**
* 根据类型查询分类
* @param type
* @return
*/
List<Category> list(Integer type);
接下来去CateServiceImpl中实现这个方法
3)CategoryServiceImpl
/**
* 根据类型查询分类
* @param type
* @return
*/
public List<Category> list(Integer type) {
return categoryMapper.list(type);
}
接下来去CategoryMapper中声明list方法,因为需要动态添加status=1的额外条件来进行查询,所以把具体的实现语句放在CategoryMapper.xml文件中来实现
4)CategoryMapper
/**
* 根据类型查询分类
* @param type
* @return
*/
List<Category> list(Integer type);
5)CategoryMapper.xml
<select id="list" resultType="Category">
select * from category
where status = 1
<if test="type != null">
and type = #{type}
</if>
order by sort asc,create_time desc
</select>
到这里就完成了根据type返回分类的操作啦!
2. 根据分类id查询对应哪些菜品,返回菜品列表List<Dish>
(1)思路梳理
刚刚我们通过type获得了分类,接下来就要根据获得的分类来查询菜品啦。“根据分类id查询该分类下对应了哪些菜品”这个接口实现下图的功能2。
现在我们有了分类列表category、也有了菜品列表dish,即将完善的是套餐列表setmeal和套餐对应的菜品列表setmeal_dish。
分类列表category如下图所示:
分类列表的type列描述了分类的类型,其中1表示菜品分类,2表示套餐分类。只有type=2的分类id会出现在setmeal表中。setmeal表的具体内容如下图所示:
dish表中对应的category_id是这道菜所归属的菜品分类的id,它不包含13和15的,因为13和15是category中标志着“套餐分类”的id。dish表的内容如下图所示。
根据黑马资料里给出的数据库设计文档(如下图所示),setmeal_dish表整合了setmeal表对应的id、dish表对应的id,用来表示“A套餐(通过setmeal_id来标记)由归属于C菜品、D菜品和E菜品等组成(C、D、E等菜品分别有自己的dish_id,而dish表中又有它们分别对应的category_id)”。
(2)代码实现
1)DishController
返回类型是一个列表,通过category_id查询当前类别中有哪些菜品。所以category_id做参数。
/**
* 根据分类id查询菜品
* @param categoryId
* @return
*/
@GetMapping("/list")
@ApiOperation("根据分类id查询菜品")
public Result<List<Dish>> list(Long categoryId){
List<Dish> list = dishService.list(categoryId);
return Result.success(list);
}
2)DishService
在DishService.java的接口类中记录list方法
/**
* 根据分类id查询菜品
* @param categoryId
* @return
*/
List<Dish> list(Long categoryId);
3)DishServiceImpl
在实现类中,具体地实现list方法,能够根据分类id查询到菜品,并且以列表的形式返回。这里创建了一个 Dish 对象,使用了建造者模式(Builder Pattern)来构建对象。①categoryId(categoryId) 设置了菜品对象的分类ID属性为传入的 categoryId 参数;②status(StatusConstant.ENABLE) 设置了菜品对象的状态为启用状态,这里使用了一个常量 StatusConstant.ENABLE 来表示启用状态;③build() 方法用于构建 Dish 对象。
/**
* 根据分类id查询菜品
* @param categoryId
* @return
*/
public List<Dish> list(Long categoryId) {
Dish dish = Dish.builder()
.categoryId(categoryId)
.status(StatusConstant.ENABLE)
.build();
return dishMapper.list(dish);
}
接下来我们还需要在DishMapper中声明**“根据传入的动态dish信息,将查询到的菜品以列表形式返回”**的方法,并在DishMapper.xml中具体实现这一功能。
4)DishMapper
/**
* 动态条件查询菜品
* @param dish
* @return
*/
List<Dish> list(Dish dish);
5)DishMapper.xml
对传入的name、category_id、status分别做判断
<select id="list" resultType="Dish" parameterType="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>
到这里,根据分类id查询菜品的功能就已经完成了!
(3)图片上传功能
在Day03已经实现了。
3. 新增套餐setmeal
这个功能完全可以仿照Day03的新增菜品来进行实现
1) SetmealContorller
/**
* 套餐管理
*/
@RestController
@RequestMapping("/admin/setmeal")
@Api(tags = "套餐相关接口")
@Slf4j
public class SetmealController {
@Autowired
private SetmealService setmealService;
/**
* 新增套餐
* @param setmealDTO
* @return
*/
@PostMapping
@ApiOperation("新增套餐")
public Result save(@RequestBody SetmealDTO setmealDTO) {
setmealService.saveWithDish(setmealDTO);
return Result.success();
}
}
2) SetmealService
public interface SetmealService {
/**
* 新增套餐,同时需要保存套餐和菜品的关联关系
* @param setmealDTO
*/
void saveWithDish(SetmealDTO setmealDTO);
}
3) SetmealServiceImpl
/**
* 套餐业务实现
*/
@Service
@Slf4j
public class SetmealServiceImpl implements SetmealService {
@Autowired
private SetmealMapper setmealMapper;
@Autowired
private SetmealDishMapper setmealDishMapper;
@Autowired
private DishMapper dishMapper;
/**
* 新增套餐,同时需要保存套餐和菜品的关联关系
* @param setmealDTO
*/
@Transactional
public void saveWithDish(SetmealDTO setmealDTO) {
Setmeal setmeal = new Setmeal();
BeanUtils.copyProperties(setmealDTO, setmeal);
//向套餐表插入数据
setmealMapper.insert(setmeal);
//获取生成的套餐id
Long setmealId = setmeal.getId();
List<SetmealDish> setmealDishes = setmealDTO.getSetmealDishes();
setmealDishes.forEach(setmealDish -> {
setmealDish.setSetmealId(setmealId);
});
//保存套餐和菜品的关联关系
setmealDishMapper.insertBatch(setmealDishes);
}
}
接下来需要再setmeal表中插入套餐数据,还要在setmea_dish表中插入套餐与菜品的关联数据。我们首先来看setmeal表中插入套餐数据的实现
4)SetmealMapper和SetmealMapper.xml
/**
* 新增套餐
* @param setmeal
*/
@AutoFill(OperationType.INSERT)
void insert(Setmeal setmeal);
有较多动态参数的传入,我们去SetmealMapper.xml中去进行实现
<insert id="insert" parameterType="Setmeal" useGeneratedKeys="true" keyProperty="id">
insert into setmeal(category_id, name, price, status, description, image, create_time, update_time, create_user, update_user)
values (#{categoryId}, #{name}, #{price}, #{status}, #{description}, #{image}, #{createTime}, #{updateTime},
#{createUser}, #{updateUser})
</insert>
5)SetmeaDishMapper和SetmeaDishMapper.xml
为了向setmeal_dish表中插入当前套餐对应的所有菜品。
/*
* 批量保存菜品和套餐的关联关系
* @param setmealDishes
* */
void insertBatch(List<SetmealDish> setmealDishes);
以及SetmeaDishMapper.xml内容的实现
<insert id="insertBatch" parameterType="list">
insert into setmeal_dish
(setmeal_id,dish_id,name,price,copies)
values
<foreach collection="setmealDishes" item="sd" separator=",">
(#{sd.setmealId},#{sd.dishId},#{sd.name},#{sd.price},#{sd.copies})
</foreach>
</insert>
新增菜品功能大功告成!
二、 套餐管理功能——分页查询
这段也是仿照菜品分页查询来进行实现的,具体的实现代码黑马的文档里已经很清楚了,复制粘贴好累,就不贴啦~
分页查询的功能测试我是通过接口文档来进行的,大概是下面这个样子
三. 删除套餐
和删除菜品是一样的!先判断当前id的套餐是否处于起售状态,起售状态的套餐是不能被删除的。但是删除菜品时需要判断菜品是否被套餐关联了,删除套餐就不用这个判断了,更简单了一点点。
(1)代码实现
SetmealController和SetmealService就不说了,
下面这段代码是SetmealServiceImpl中关于删除套餐的具体实现
所以我们需要在setmealMapper中完成getById和deleteById方法
在setmealDishMapper中完成deleteBySetmeal方法
1)setmealMapper
2)setmealDishMapper
这个功能通过前后端联调测试一下,以上代码是没有问题的
四、修改套餐
还是仿照修改菜品的那个
1. 根据套餐id查询套餐及对应菜品的信息
(1)代码实现
1)SetmealController
接下来去声明SetmealService中的getByIdWithDish方法
2)SetmealService
3) 实现类
接下来该去SetmealDishMapper里实现getBySetmealId的方法
4)SetmealDishMapper
2. 修改套餐内容
(1)代码实现
1) SetmealController
2) SetmealService
3) 实现类
4) SetmealMapper和对应的.xml文件
黑马的文档里怎么没有SetmealMapper里的那段啊!!!
因为这个报错调了好久!
以及
<update id="update">
update setmeal
<set>
<if test="categoryId!=null">
category_id=#{categoryId},
</if>
<if test="name!=null">
name=#{name},
</if>
<if test="price!=null">
price=#{price},
</if>
<if test="status!=null">
status=#{status},
</if>
<if test="description!=null">
description=#{description},
</if>
<if test="image!=null">
image=#{image},
</if>
<if test="createTime!=null">
create_time=#{createTime},
</if>
<if test="updateTime!=null">
update_time=#{updateTime},
</if>
<if test="createUser!=null">
create_user=#{createUser},
</if>
<if test="updateTime!=null">
update_time=#{updateTime}
</if>
</set>
</update>
5)最后还有一个SetmealDishMapper
/**
* 根据套餐id查询套餐和菜品的关联关系
* @param setmealId
* @return
*/
@Select("select * from setmeal_dish where setmeal_id = #{setmealId}")
List<SetmealDish> getBySetmealId(Long setmealId);