因为黑马这里的功能是直接导入的代码,所以在这里做一个复盘~下图是分类管理需要实现的接口。

这里的分类管理解析一下,我们有一个category表需要管理,它把菜品分为两类,一类是套餐,一类是菜品类别,这里面又细分了(比如特色蒸菜)。所以最开始看的时候有点奇怪的点,就是大方向分为两类,之后两类里面又有自己的细分。如下图所示

type表示是套餐还是菜品分类,但是本身有unique的name以及id,所以就是管理这个表。
还是老样子,先创建一个controller类给它加上@RequestMapping注解以及@RestController告诉spring这是一个controller类。

- 先做新增分类这个接口,接口内容如下图所示。


显然传入的时候是JSON数据会有一个分类名称以及sort(分数)以及它是套餐or菜品所以后端接收的时候需要@RequestBody注解,且一般接收这种我们需要重新定义一个对象叫categoryDTO,返回的时候不需要携带什么返回前端。

这里忘记说了记得把category的service注入进来先。controller写完去service实现,本质就是加入category表中。思考一下需要特判什么条件吗?好像没有,但是新增的时候我们最好默认该分类的状态(STATUS)为0。不然还没给该分类添加菜品就上架了。传入数据库我们需要的是entity对象,但是前端传来的是DTO对象,这里需要对象转换,并且需要AOP来自动传入createUser这些(这个是写在Mapper层)。

最后进入Mapper层写一个insert方法也即是SQL。这里复习一下insert的DML操作。
insert into 表名 (属性s)values (数据s)

这里需要注意的点就是上面粉色的对应数据库的字段需要一致,下面白色字段对应entity中的字段。最后Autofill就是AOP这个有点复杂可以讲一下也是给自己复习一下,但是没必要细钻。

在这里AOP的拦截发生在Mapper层的方法执行前!


这里前面几点说的都比较清晰了,最后一次用到了ThreadLocal其实就是为了createUser,updateUser这两个值,需要填写当前登录的用户。
总结就是下图所示:

OK新增分类就到这里。
- 分类分页查询
我们有了数据是不是需要展示出来,这里就需要分页查询了,之前的employee管理的时候已经实现了其实,就是利用PageHelper帮助分页并且得到Total以及返回前端的时候需要用PageResult返回。controller层的代码如下所示:

如果没记错的话DTO里面应该只有一个page以及pagesize(这俩是必须的)但是还可以加俩字段用于精确查询(name,type)一个表示分类名字这个是unique的在数据库中,type就是这是套餐还是菜品。
进入Service层,需要利用pageHelper,并且Mapper层查询到的结果是一个List,这里的page就是和list一样的功能,但是它多了一个total去统计总共多少records。

在这里的Mapper就不能直接用注解下SQL了,因为前面提到了可能会传入name or type 所以需要利用动态SQL,写在XML里面。如下图所示:

这里也有需要注意的点,resulType是category实体类,不是list<category>,因为这里指代的是一条数据。以及<where的作用可以自动去除if中的多余and防止SQL语句出错!
- 删除分类
删除分类需要分析一下,不能闷头写了,如果这个分类关联了菜品或者套餐不能删除。

前端传过来的是分类的ID即主键!这里有两点注意,1、是利用Query传参,即把参数挂在URL的❓后面以键值对的形态传递。这里的接收方式如下所示。

总结完了就可以写controller层了如下图所示:

这里就是上面说的单参数名一致的方法接收。之后进行service层实现具体的业务逻辑。
因为前面我们说了需要查询该分类是否关联了菜品或者套餐,所以这里的service同时还需要注入dish和setmeal的Mapper层。再看看这两个表是否有通过categoryId能查询,结论:可以通过categoryId查询到对应的菜品和套餐。一个分类里可能关联多个套餐和菜品,所以我们查询出来直接判断size大小即可。Service的实现如下图所示:

之后的categoryMapper的delete就通过前端得到的ID进行删除就好了。
- 修改分类

从上述图中可以得到,用的PUT方法,并且是用过json传递参数,包括id,name,sort,type四个参数,通常从前端接收用的是DTO,别忘记了@RequestBody
controller层如下图所示

修改和新增的逻辑其实是差不多的只不过修改是在原有的基础上,但是Service传给mapper的类型都应该是entity所以在这里还要将前端传入的DTO转为entity类型传给Mapper。

Mapper那里别忘了利用AOP实现updateTime和updateUser的设置如下图:

同时这里的update需要采用动态SQL理由如下:

以及利用<Set>的黑魔法,会自动去除末尾的逗号,所以在XML中的SQL如下图所示:

- 更新状态
其实就是用上面的update将前端传入的status封装进entity中调用mapper层的update方法就好了,
这里需要说一下前端的数据传输如下图所示:

一个Path参数一个Query参数如下图所示


路径传参数需要在前面添加@PathVariable 后头那个Query最好也加一个@RequestParam
下面是controller和service层的代码实现


- 根据类型查询分类
这个接口不像前面的感觉很具体,这个就感觉很抽象,该接口在后续别的模块中起到辅助作用,如下图所示:


接下里看下接口文档

只有一个Query传入分类。返回值就多了如下图所示:

返回的就是entity数组,所以这里controller的Result中的泛型应该是List<category>,至于为什么是这样就像上面说的前端会根据返回值将id隐藏到选项中,一旦选择了某个菜品分类,就会自动赋值categoryid,像新增菜品中是如何得到categoryid就是这样得到的。
controller代码如下图所示:

注意返回的是一个List,而service层也只需要通过type查询分类如下图所示:

但是在Mapper层查询的时候SQL需要判断当前菜品分类or套餐分类的状态要是启动的不然没必要查。

这个动态SQL就是实现了三个功能,1、查询菜品分类 2、套餐分类 3、全查。