Day03 公共字段填充与菜品管理

在前面两天就有提及比如新增员工、新增分类这些功能,我们都需要添加createUser、createTime、updateUser、updateTime这些字段的数据,但是如果每次都要自己加一段代码未免太过麻烦,并且如果以后需要修改一段一段改到猴年马月?

这就引出了我们的AOP(面向切面编程 Spring中IOC DI AOP三大)其中之一!

在苍穹外卖这个项目中一般是在Mapper层的方法设置!

首先我们需要定义一个枚举类告诉AOP哪些方法需要自动填充,例如insert需要填充四个字段,而update只需要两个字段。所以才需要枚举类!

这里我给自己讲一下这个代码的语法以及作用吧(因为这些没咋学)

首先我们给操作方法定义了一个枚举类,所以 why enum?

这个OperationType就和String一样是一个封装好的类了。

然后是自定义注解的语法:

在AutoFill这个注解中定义了一个value属性,到时候可以指定这个注解修饰的方法是Insert还是Update!从而去动态调整需要填充的字段.............

自定义完注解以及枚举类后需要定义切面类了(也就是实现上面自动填充的类)

用@Aspect表示这个类是一个切面类,并且用@Component告诉Spring这个类的存在!

定义完成切面类后,需要定义切入点!

切入点存在的意义就是告诉我们Spring需要监控哪些方法,利用@Pointcut这个注解.......

切入点定义完后就是编写业务的实现逻辑了,还记得业务逻辑吗(我们要在Insert和Update之前给字段自动填充)

这里不只有Before这一种,我记得有什么Around等等,这里我们用Before理由图中写了..........

第一段代码的逻辑就是拿到这个方法到底是update还是insert,这个取决了我们填充字段的个数~

接下来就是获取方法里面的参数(通常就是entity)我们需要通过反射往这个entity的属性注入数据!

这里的UserId是通过ThreadLocal得到的,这个也是一个知识点~~~我们会在校验登录的JWT令牌通过后把UserId传到ThreadLocal上.....公共字段填充就到此为止了.......






菜品管理开发

先看相关的接口文档有哪些接口!

1、新增菜品功能

前端通过Json传输需要添加的菜品数据,所以我们需要用@RequestBody修饰一个对象进行接收.....接收前端传过来的我们一般定义一个DishDTO对象如下图所示:

所以我们的controller代码先写模块如下图所示:

新增菜品的接口controller方法如下:

在service层处理dishDTO,这里的新增菜品并不是简单的往Dish表中加一个菜品这么简单,它还有一个Flavor表里面装着每个菜品它的口味,所以同时我们还要更新Flavor表~~

(1)首先是先给Dish表新增,通常是将DTO对象转为entity,service部分代码如下图所示:

这里是insert操作,所以可以用上我们在前面做的AOP自动填充字段!这里的SQL比较特殊由于Flavor表需要记录dish_id但是这里我们的dish还未存进表里,自己也不清楚id是多少,所以利用动态SQL的操作且SQL中id(auto_increment)功能在插入之后自动将id写入entity中!代码如下所示:

上述两图表示AOP的自动填充字段,即在执行下方的SQL之前会自动把四个字段填充到dish中...随后执行下方的SQL,执行完后会把自动生成的id也赋给dish..

(2)其次给Flavor表添加数据由于一个dish对应多个flavor所以前端DTO传过来的是一个List<Flavor>

下面给出Flavor的entity对象定义:

这里的dishId最初都不知道,在dish插入表中由SQL自增得到,所以我们需要给前端传来的List<Flavor> flavors用for循环调用set方法给Flavor中的dishId进行赋值.....代码如下所示:

这里的SQL我们不用for循环一个一个插入,而是利用动态SQL的机制写成一条SQL插入提高效率!

  1. 菜品分页查询

经典的将菜品查询并且展示出来............如图所示:

分页查询接口文档如下图所示:

前端通过Query传递参数,也就是通过在url的问号后面以键值对的形式传参,page和pagesize是必须的,这玩意参数不定,所以还是要用一个对象来接收DishPageQueryDTO如下图所示:

后端需要返回给前端total以及records这里的records是一个List数组且里面存储的对象需要包含如下字段:

后端返回值包括了一个categoryName这个在Dish这个entity中没有,通常我们会把后端返回的数据包装了一个VO对象如下图所示:

这里我们用不上这个List<DishFlavor>但是之后在修改菜品的时候可以用上......

所以我们的controller代码中经典调用QueryPage帮我们进行分页查询~~~

哦对了这里的返回值是PageResult对象是因为后端返回的是一个total一个records封装在里头了records由VO们组成!

在service层得到查询的结果封装到Page<DishVO>中 ,这其实就是一个List但是多了一个Total属性

在Mapper层由于前端可能还会送过来name和categoryID进行模糊查询所以采用动态SQL,XML里代码如下:

知识点就是需要left join找到categoryName以及<where 会自动删除if里面的and这个功能~~

  1. 菜品批量删除功能

这里需要注意一下细节:

所以我们controller层的代码如下:

service层需要判断一下

(1)菜品是否处在起售状态

用id一个一个取出来判断吧,懒得优化了~

(2)菜品是否和套餐关联

就拿id去查setmealDish表,如果能查到数据就代表有关联,查不到就表示没有

这个的SQL用的foreach优化的查询

这里我们用的where dish_id in (id1,id2,id3)就是这是批量删除如果有一个关联了就不能删除!

  1. 根据id查询菜品

观察接口文档,显然这里的返回需要用到DishVO,且前端的参数传递是利用在url中直接传递所以需要加@PathVariable

controller代码如下图:

由于我们不仅仅要查菜品信息还有flavor的信息,也就是需要查两张表!所以在service需要同时注入dishmapper和flavormapper!

这简单来说就是把从两张表里面能查出来的封装进VO对象中返回就好了,查询的Mapper就比较简单不说了~

  1. 修改菜品信息

前端通过json传递参数,参数可以用DishDTO接收~这里没有什么需要返回给前端的所以代码如下:

显然我们需要修改dish表和flavor表~ dish表好说用一手动态SQLupdate就好了,但是这个flavor的update可能是增加数据、减少、更新。所以我们选择删除相关dish的flavor重新插入!

用到的mapper层有dish以及flavor,一个是update一个是insertBatch

update采用set if可以动态调整 这里不要忘记了set的作用~

insertBatch顾名思义用了foreach~~~~

  1. 修改菜品状态

这个其实本质上也是菜品信息的修改一种,我们把status封装一个Dish对象里面传给DishMapper的update就好了

就是注意前端传参数的情况~

这里的id是用Query传递的,怕不好分辨可以加一个@RequestParam("前端字段")

  1. 根据分类id查询菜品

这里一个分类可能拥有多个菜品,所以查出来的应该是一个List<Dish>,简单说一下前端就通过Query传递了一个categoryId 后端需要返回一个List<Dish>

service再去dishmapper调用一下getByIdDishId就好了,这里其实名字取错了应该叫categoryId而不是DishId

SQL中第一个name写在where里面可能是为了以后的精确查询奠定基础?其实有点多余了~~

相关推荐
独自破碎E2 小时前
如何防止接口被恶意刷量?
java·开发语言
期待のcode2 小时前
Java的单例模式
java·开发语言·单例模式
断春风2 小时前
从 JDK 8 到 JDK 21:企业级 Java 版本选择的架构思考
java·架构·jdk
h7ml2 小时前
构建可扩展的企业微信消息推送服务:事件驱动架构在Java中的应用*
java·架构·企业微信
heartbeat..3 小时前
JavaWeb 核心:HttpServletRequest 请求行、请求头、请求参数完整梳理
java·网络·web·request
Aliex_git3 小时前
内存堆栈分析笔记
开发语言·javascript·笔记
LYOBOYI1233 小时前
qml练习:创建地图玩家并且实现人物移动(2)
开发语言·qt
电商API&Tina3 小时前
【电商API接口】多电商平台数据API接入方案(附带实例)
运维·开发语言·数据库·chrome·爬虫·python·jenkins
叫我莫言鸭3 小时前
关于word生成报告的POI学习2循环标题内容
java·学习·word