瑞吉外卖day05:增删改查分类以及公共字段自动填充腾讯云开发者社区

而针对于这些字段,我们的赋值方式为:

目前,在我们的项目中处理这些字段都是在每一个业务方法中进行赋值操作,如下:

如果都按照上述的操作方式来处理这些公共字段,需要在每一个业务方法中进行操作,编码相对冗余、繁琐,那能不能对于这些公共字段在某个地方统一处理,来简化开发呢?

答案是可以的,我们使用MybatisPlus提供的公共字段自动填充功能。

1.2.1思路分析

MybatisPlus公共字段自动填充,也就是在插入或者更新的时候为指定字段赋予指定的值,使用它的好处就是可以统一对这些字段进行处理,避免了重复代码。在上述的问题分析中,我们提到有四个公共字段,需要在新增/更新中进行赋值操作,具体情况如下:

字段名

赋值时机

说明

createTime

插入(INSERT)

updateTime

插入(INSERT),更新(UPDATE)

createUser

updateUser

实现步骤:

1、在实体类的属性上加入@TableField注解,指定自动填充的策略。

2、按照框架要求编写元数据对象处理器,在此类中统一为公共字段赋值,此类需要实现MetaObjectHandler接口。

1.2.2代码实现

1).实体类的属性上加入@TableField注解,指定自动填充的策略。

在员工Employee实体类的公共字段属性上,加上注解,指定填充策略。(ps.在资料中提供的实体类,已经添加了该注解,并指定了填充策略)

FieldFill.INSERT:插入时填充该属性值FieldFill.INSERT_UPDATE:插入/更新时填充该属性值

2).按照框架要求编写元数据对象处理器,在此类中统一为公共字段赋值,此类需要实现MetaObjectHandler接口。

所属包:com.itheima.reggie.common

编写完了元数据对象处理器之后,我们就可以将之前在新增和修改方法中手动赋值的代码删除或注释掉。

然后,我们启动项目,在员工管理模块中,测试增加/更新员工信息功能,然后通过debug或者直接查询数据库数据变更的形式,看看我们在新增/修改数据时,这些公共字段数据是否能够完成自动填充。

1.3.1思路分析

那么我先搞清楚一点,当我们在修改员工信息时,我们业务的执行流程是什么样子的,如下图:

1).LoginCheckFilter的doFilter方法

2).EmployeeController的update方法

3).MyMetaObjectHandler的updateFill方法

我们可以在上述类的方法中加入如下代码(获取当前线程ID,并输出):

longid=Thread.currentThread().getId();log.info("线程id为:{}",id);执行编辑员工功能进行验证,通过观察控制台输出可以发现,一次请求对应的线程id是相同的:

经过上述的分析之后,发现我们可以使用JDK提供的一个类,来解决此问题,它是JDK中提供的ThreadLocal。

1.3.2ThreadLocal

ThreadLocal并不是一个Thread,而是Thread的局部变量。当使用ThreadLocal维护变量时,ThreadLocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。

ThreadLocal为每个线程提供单独一份存储空间,具有线程隔离的效果,只有在线程内才能获取到对应的值,线程外则不能访问当前线程对应的值。

ThreadLocal常用方法:

A.publicvoidset(Tvalue):设置当前线程的线程局部变量的值

B.publicTget():返回当前线程所对应的线程局部变量的值

C.publicvoidremove():删除当前线程所对应的线程局部变量的值

1.3.3操作步骤

1).编写BaseContext工具类,基于ThreadLocal封装的工具类

1.3.4代码实现

1).BaseContext工具类

1.3.5功能测试

后台系统中可以管理分类信息,分类包括两种类型,分别是菜品分类和套餐分类。当我们在后台系统中添加菜品时需要选择一个菜品分类,当我们在后台系统中添加一个套餐时需要选择一个套餐分类,在移动端也会按照菜品分类和套餐分类来展示对应的菜品和套餐。

在分类管理中,我们新增分类时,可以选择新增菜品分类(川菜、湘菜、粤菜...),也可以选择新增套餐分类(营养早餐、超值午餐...)。在添加套餐的时候,输入的排序字段,控制的是移动端套餐列表的展示顺序。

新增分类,其实就是将我们新增窗口录入的分类数据,插入到category表,具体表结构如下:

我们添加的套餐名称,是唯一的,不能够重复的,所以在设计表结构时,已经针对于name字段建立了唯一索引,如下:

在开发代码之前,需要梳理一下整个程序的执行过程:

1).在页面(backend/page/category/list.html)的新增分类表单中填写数据,点击"确定"发送ajax请求,将新增分类窗口输入的数据以json形式提交到服务端

2).服务端Controller接收页面提交的数据并调用Service将数据进行保存

3).Service调用Mapper操作数据库,保存数据

可以看到新增菜品分类和新增套餐分类请求的服务端地址和提交的json数据结构相同,所以服务端只需要提供一个方法统一处理即可:

具体请求信息整理如下:

请求

请求方式

POST

请求路径

/category

请求参数

json格式-{"name":"川菜","type":"1","sort":2}

代码实现的具体步骤如下:

1).实体类Category

所属包:com.itheima.reggie.entity

所属包:com.itheima.reggie.mapper

所属包:com.itheima.reggie.service

importcom.baomidou.mybatisplus.extension.service.IService;importcom.itheima.reggie.entity.Category;publicinterfaceCategoryServiceextendsIService<Category>{}4).业务层实现类CategoryServiceImpl

所属包:com.itheima.reggie.service.impl

importcom.itheima.reggie.common.R;importcom.itheima.reggie.entity.Category;importcom.itheima.reggie.service.CategoryService;importlombok.extern.slf4j.Slf4j;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.*;/***分类管理*/@RestController@RequestMapping("/category")@Slf4jpublicclassCategoryController{@AutowiredprivateCategoryServicecategoryService;/***新增分类*@paramcategory*@return*/@PostMappingpublicRsave(@RequestBodyCategorycategory){log.info("category:{}",category);categoryService.save(category);returnR.success("新增分类成功");}}2.5功能测试新增分类的代码编写完毕之后,我们需要重新启动项目,进入管理系统访问分类管理,然后进行新增分类测试,需要将所有情况都覆盖全,例如:

1).输入的分类名称不存在

2).输入已存在的分类名称

3).新增菜品分类

4).新增套餐分类

系统中的分类很多的时候,如果在一个页面中全部展示出来会显得比较乱,不便于查看,所以一般的系统中都会以分页的方式来展示列表数据。

1).页面发送ajax请求,将分页查询参数(page、pageSize)提交到服务端

2).服务端Controller接收页面提交的数据并调用Service查询数据

3).Service调用Mapper操作数据库,查询分页数据

4).Controller将查询到的分页数据响应给页面

5).页面接收到分页数据并通过ElementUI的Table组件展示到页面上

页面中使用的是ElementUI提供的分页组件进行分页条的展示:

我们通过浏览器,也可以抓取到分页查询的请求信息,如下:

具体的请求信息整理如下:

GET

/category/page

page=1&pageSize=10

在CategoryController中增加分页查询的方法,在方法中传递分页条件进行查询,并且需要对查询到的结果,安排设置的套餐顺序字段sort进行排序。

/***分页查询*@parampage*@parampageSize*@return*/@GetMapping("/page")publicRpage(intpage,intpageSize){//分页构造器PagepageInfo=newPage<>(page,pageSize);//条件构造器LambdaQueryWrapperqueryWrapper=newLambdaQueryWrapper<>();//添加排序条件,根据sort进行排序queryWrapper.orderByAsc(Category::getSort);//分页查询categoryService.page(pageInfo,queryWrapper);returnR.success(pageInfo);}3.4功能测试分页查询的代码编写完毕之后,我们需要重新启动项目,然后登陆系统后台,点击分类管理,查询分类列表是否可以正常展示。测试过程中可以使用浏览器的监控工具查看页面和服务端的数据交互细节。

测试完毕后,大家会发现,我们查询数据库返回的类型为1或者2,但是实际展示到页面上的却是"菜品分类"或"套餐分类",这一块是在前端页面中进行处理的,处理代码如下:

在分类管理列表页面,可以对某个分类进行删除操作。需要注意的是当分类关联了菜品或者套餐时,此分类不允许删除。

在前端页面中,点击"删除"按钮,就会触发定义的方法,然后往服务端发送异步请求,并传递参数id,执行删除分类操作。

删除操作的具体执行流程如下:

1).点击删除,页面发送ajax请求,将参数(id)提交到服务端

2).服务端Controller接收页面提交的数据并调用Service删除数据

3).Service调用Mapper操作数据库

从上述的分析中,我们可以得到请求的信息如下:

DELETE

id=1395291114922618881

在CategoryController中增加根据ID删除的方法,在方法中接收页面传递参数id,然后执行删除操作。

/***根据id删除分类*@paramid*@return*/@DeleteMappingpublicRdelete(Longid){log.info("删除分类,id为:{}",id);categoryService.removeById(id);returnR.success("分类信息删除成功");}4.4功能测试基本的删除操作代码实现完毕后,重启项目,进行测试。可以通过debug断点调试进行测试,同时结合浏览器监控工具查看请求和响应的具体数据。

4.5.1思路分析

在上述的测试中,我们看到分类数据是可以正常删除的。但是并没有检查删除的分类是否关联了菜品或者套餐,所以我们需要进行功能完善。完善后的逻辑为:

那么在这里又涉及到我们后面要用到的两张表结构dish(菜品表)和setmeal(套餐表)。具体的表结构,我们目前先了解一下:

4.5.2准备工作

1).准备菜品(Dish)及套餐(Setmeal)实体类(课程资料中直接拷贝)

importcom.baomidou.mybatisplus.core.mapper.BaseMapper;importcom.itheima.reggie.entity.Dish;importorg.apache.ibatis.annotations.Mapper;@MapperpublicinterfaceDishMapperextendsBaseMapper{}代码语言:javascript复制importcom.baomidou.mybatisplus.core.mapper.BaseMapper;importcom.itheima.reggie.entity.Setmeal;importorg.apache.ibatis.annotations.Mapper;@MapperpublicinterfaceSetmealMapperextendsBaseMapper{}3).Service接口DishService和SetmealService

importcom.baomidou.mybatisplus.extension.service.IService;importcom.itheima.reggie.entity.Dish;publicinterfaceDishServiceextendsIService{}代码语言:javascript复制importcom.baomidou.mybatisplus.extension.service.IService;importcom.itheima.reggie.entity.Setmeal;publicinterfaceSetmealServiceextendsIService{}4).Service实现类DishServiceImpl和SetmealServiceImpl

importcom.baomidou.mybatisplus.extension.service.impl.ServiceImpl;importcom.itheima.reggie.entity.Dish;importcom.itheima.reggie.mapper.DishMapper;importcom.itheima.reggie.service.DishService;importlombok.extern.slf4j.Slf4j;importorg.springframework.stereotype.Service;@Service@Slf4jpublicclassDishServiceImplextendsServiceImplimplementsDishService{}代码语言:javascript复制importcom.baomidou.mybatisplus.extension.service.impl.ServiceImpl;importcom.itheima.reggie.entity.Setmeal;importcom.itheima.reggie.mapper.SetmealMapper;importcom.itheima.reggie.service.SetmealService;importlombok.extern.slf4j.Slf4j;importorg.springframework.stereotype.Service;@Service@Slf4jpublicclassSetmealServiceImplextendsServiceImplimplementsSetmealService{}4.5.3代码实现

1).创建自定义异常

在业务逻辑操作过程中,如果遇到一些业务参数、操作异常的情况下,我们直接抛出此异常。

所在包:com.itheima.reggie.common

/***自定义业务异常类*/publicclassCustomExceptionextendsRuntimeException{publicCustomException(Stringmessage){super(message);}}2).在CategoryService中扩展remove方法

publicinterfaceCategoryServiceextendsIService{//根据ID删除分类publicvoidremove(Longid);}3).在CategoryServiceImpl中实现remove方法

异常抛出之后,会被异常处理器捕获,我们只需要在异常处理器中捕获这一类的异常,然后给页面返回对应的提示信息即可。

4).在GlobalExceptionHandler中处理自定义异常

在全局异常处理器中增加方法,用于捕获我们自定义的异常CustomException

/***异常处理方法*@return*/@ExceptionHandler(CustomException.class)publicRexceptionHandler(CustomExceptionex){log.error(ex.getMessage());returnR.error(ex.getMessage());}5).改造CategoryController的delete方法

注释掉原有的代码,在delete方法中直接调用categoryService中我们自定义的remove方法。

/***根据id删除分类*@paramid*@return*/@DeleteMappingpublicRdelete(Longid){log.info("删除分类,id为:{}",id);//categoryService.removeById(id);categoryService.remove(id);returnR.success("分类信息删除成功");}4.5.4功能测试

功能完善的代码编写完毕之后,我们需要重新启动项目,进入管理系统访问分类管理,然后进行删除分类的测试,需要将所有情况都覆盖全,例如:

1).新增一个分类,然后再直接删除,检查是否可以正常删除成功。(新增的分类时没有关联菜品和套餐的)

2).在数据库表(dish/setmeal)中,找到一个与菜品或套餐关联的分类,然后在页面中执行删除操作,检查是否可以正常的提示出对应的错误信息。

在分类管理列表页面点击修改按钮,弹出修改窗口,在修改窗口回显分类信息并进行修改,最后点击确定按钮完成修改操作。

这里面大家会发现,修改功能我们还没有实现,但是当点击"修改"按钮的时候,我们并没有开发根据ID查询数据,进行页面回显的功能,但是页面的分类数据确实回显回来了。这是怎么做到的呢,我们来解析一下前端的代码实现(前端代码已经实现):

那么回显这一步的操作前端已经实现,我们就只需要开发一个方法,修改操作的方法即可。我们可以通过浏览器来抓取一下修改操作的请求信息,如图:

具体的请求信息,整理如下:

PUT

{id:"1399923597874081794",name:"超值午餐",sort:0}

/***根据id修改分类信息*@paramcategory*@return*/@PutMappingpublicRupdate(@RequestBodyCategorycategory){log.info("修改分类信息:{}",category);categoryService.updateById(category);returnR.success("修改分类信息成功");}5.4功能测试按照前面分析的操作流程进行测试,查看数据是否正常修改即可。

THE END
1.高德POI分类代码一览表.pdf文档全文预览内容提供方:00625 大小:245.02 KB 字数:约5.41万字 发布时间:2019-01-06发布于湖北 浏览人气:3069 下载次数:仅上传者可见 收藏次数:0 需要金币:*** 金币 (10金币=人民币1元)高德POI分类代码一览表.pdf 关闭预览 想预览更多内容,点击免费在线预览全文 免费在线预览全文 高德POI分类代码一览表 (此https://max.book118.com/html/2019/0103/5001131114001344.shtm
2.莆田学院附属医院后勤一站式服务社会化采购项目服务类采购项目附件4、招标内容及要求:详见《采购标的一览表》及招标文件第五章。 5、需要落实的政府采购政策:无 6、投标人的资格要求 6.1法定条件:符合政府采购法第二十二条第一款规定的条件。 6.2特定条件: 包:1 6.3是否接受联合体投标:不接受。 ※根据上述资格要求,投标文件中应提交的“投标人的资格及资信证明文件”详见招标文件http://u002fwww.ptzfcg.gov.cn/upload/document/20211228/4b0559cfb42f4bdd868f717971a312ca.html
3.Tableau选餐厅数据看板7、第七个图表是菜品均分 image 8、第八个图表是餐厅一览表 image 9、最后的 BI 看板(仪表盘) image image 有了这个 BI 看板之后,你就再也不要纠结吃什么了,只有你输入所在的城市、菜系、环境、口味、服务、预算等要求,就能自动筛选出对应餐厅的店名和所在的地址。https://www.jianshu.com/p/b2c50c2e0a88
4.超市促销活动方案策划流程(模板18篇)七、开业项目费用一览表(略) 超市促销活动方案策划流程篇8 五一节,是春节长假后的第一个黄金周,是旺季来临的标志,是全年营销的第一场大战役。因此,五一节的促销不仅不能错过,且要重视并搞好。 继三四月销售低迷后,五一节迎来了消费者消费欲望的复苏。随着春深夏至,季节性消费、换季消费开始抬头。我们综合多年的经http://www.xiefangan.com/cehuafangan/58977.html
5.软件测试bug记录表74综合管理/统计分析/菜品类别查询账单时,如果查不出账单或查询条件选择错误, 系统没有给出任何提示。 75综合管理/统计分析/退菜一览查询账单时,如果查不出账单或查询条件选择错误, 系统没有给出任何提示。 76综合管理/系统管理/优惠卡新增模块卡编号的数据类型应该限制为数字 77综合管理/系统管理/优惠卡新增模块卡https://www.360docs.net/doc/5f16594360.html
6.外卖系统数据库架构图外卖管理系统数据流图后台系统中可以管理套餐信息,通过新增套餐功能来添加一个新的套餐,在添加套餐时需要选择当前套餐所属的套餐分类和包含的菜品,并且需要上传套餐对应的图片,在移动端会按照套餐分类来展示对应的套餐。 1.2 新增套餐数据模型 新增套餐,其实就是将新增页面录入的套餐信息插入到setmeal表,还需要向setmeal_dish表插入套餐和菜https://blog.51cto.com/u_16213723/11094788
7.烧烤店菜品进销存怎么做账零代码企业数字化知识站烧烤店的菜品进销存做账可以通过以下几步来实现:1、设置菜品分类,2、记录采购信息,3、记录销售信息,4、进行库存管理,5、定期盘点和调整。其中,设置菜品分类是关键的一步,可以帮助你更好地管理各种菜品,并简化后续的记录和分析工作。通过将菜品分为肉类、海鲜、蔬菜等不同类别,你可以轻松地追踪每类菜品的采购、销售https://www.jiandaoyun.com/blog/article/1073030/
8.用英文介绍粤菜的特点特产零食粤菜是中国传统八大菜系之一,是广东省的地方菜系,以广州菜为代表。粤菜以其独特的口味、丰富的菜品和精美的制作工艺而闻名于世。下面将从风味、调料、烹饪技巧、菜品分类、烹饪方式、饮食文化等方面详细介绍粤菜的特点。 风味 粤菜的风味独特,鲜美可口,以清、鲜、爽、嫩、滑、脆、酥、香、浓、甜、酸、辣等特点著http://www.x5an.cn/tclsxan/9553.html
9.小菜单,大学问,菜单背后都蕴含着哪些经济学和美学知识?餐厅的调性不同,菜单的风格也不尽相同,然而关键的是,有些餐厅的菜单根本就谈不上风格,只能称之为价目一览表。 菜单首先给人的感觉应该是赏心悦目的,所以,在样式上,最好要有菜品的实拍图,包括在排版设计、颜色搭配上都要精心设计,各个菜之间到底应该用S型排版还是三角排版,抑或是满型版的排版,都要推敲。 https://www.iyiou.com/news/2019022893623
10.菜品列表如何实现以及如何和分类进行联动?上一篇文章我们介绍了菜品分类的功能,主要是利用侧边栏组件来实现的。在点餐场景中,当我们选择一个类目时,我们希望能看到该类目下的菜品,所以在点击类目时需要与菜品列表有联动效果。这篇文章我们就来介绍如何实现菜品列表以及如何与类目联动。 1. 菜单列表功能 https://m.bjhwtx.com/h-nd-138213.html
11.可以对餐厅的分类菜品套餐订单员工等进行管理维护本项目(瑞吉外卖)是专门为餐饮企业(餐厅、饭店)定制的一款软件产品,包括系统管理后台和移动端应用两部分。其中系统管理后台主要提供给餐饮企业内部员工使用,可以对餐厅的分类、菜品、套餐、订单、员工等进行管理维护。移动端应用主要提供给消费者使用,可以在线浏览菜品、添加购物车、下单等。 https://gitee.com/dlyjd/reggie
12.2022年内江师范学院规范性文件汇编内江师范学院3.领导干部、党员学科带头人联系青年教师情况汇总表 中共内江师范学院委员会组织部 2021年8月5日 关于开展新一轮“三分类三升级”活动的通知 各党总支(直属党支部)、党支部: 为深入贯彻落实全国、全省、全市组织部长会议精神,全面提升学院基层党组织建设质量,充分发挥基层党组织在推动学院改革发展稳定和人才培养中的https://xxgk.njtc.edu.cn/info/1631/2501.htm
13.打印机雪糕冰棍冷饮冷藏打价格标签冰箱蛋糕冰粉菜品食材日期防冻商品名称:厨房冷冻食品标签打印机雪糕冰棍冷饮冷藏打价格标签冰箱蛋糕冰粉菜品食材日期防冻贴纸肉类效期配料表 B1艾绿送1卷40*30白色冷冻标签 商品编号:10128593777503 店铺: 凯阑工业品专营店 货号:4096095137111330 类别:标签/条码打印机 接口类型:无接口 是否支持定制:定制 打印精度:305dpi 打印速度:355mm/s 条码类型https://item.jd.com/10128593777503.html