00:00
接下来我们先来编写商品服务相关的功能,首先呢,我们来编写第一个关于三级分类有关的,这个三级分类呢,是我们电商里边经常要用的一个功能,比如我们京东里边每一个商品呢,最终都会所属于某一个类别,那在最左侧呢,这个我们称为一级分类,这是最大的分类,在这个一级分类里边呢,还有一些小分类,这是第二级分类,我们称为二级分类,那每一个小分类里边呢,这个我们就称为三级分类,但这些所有的分类数据都应该是来源于数据库,我们要对它进行维护,对它进行资产改查。那我们首先呢,就需要后台管理系统来可以维护我们的整个分类数据,首先呢我们先将这些所有的分类数据,我们先来导入我们商品服务PMS相关的数据库里边,主要呢有一张表叫p Ms category,这是分类表,那这个三级分类表里边呢,这些字段各自代表的意思,首先呢看ID是我们三级分类的ID,它呢是一个自增的主键,包括我们这个name是分类的名称,每一个分类,它的负分类是什么?我们专门有一个叫parent CAD来标识它的负分类,包括呢分类所属的层级,以及当前分类是否显示零,不显示,一显示,包括分类的排序,这个分类呢,到底显示谁在先,谁在后,也会有这个排序字段,还有我们每一个分类还会有它自己的图标,包括呢,它的计量单位,比如在我们手机类下,每一个手机呢,是以一件。
01:39
来计数的,比如在我们的水各种分类下,那么有些水呢,是以一箱为计数的,那么衣服呢也是一件的,那车呢是以一辆为计数的,这是他们的计量单位,包括呢,商品数量,那就是当前分类下我们录入了多少的商品,好,这个数据表呢,就长这样,我们将数据呢先来导入进来,数据呢我们发给大家,在鼓励商城里边,打开分布式基础篇里边,我们找到代码,SQL里边呢,我们这一块是我们三级分类的数据,Ctrl a复制过来,我们呢,在这个分类表里边,我们将它打开,我们CTRLV粘贴过来,我来准备一下。
02:20
Ctrl a选中直接让它执行。好,我们所有的数据呢,就已经插入进去了三个成功,那我们来测试一下,我们将这个表呢打开重新刷新,刷新这一块呢有所有的分类数据,那么接下来对它就要进行一些增删改查,那我们呢就先来编写第一个功能,一次性查出所有的分类以及它的子分类,并把他们的以父子方式的数据结构组装起来,方便我们后台管理系统进行维护。好我们来到我们的商品服务,我们打开我们之前逆向生成的跟分类有关的controller里边,那分类呢是category controller,我们打开这一块呢,逆向生成的一个方法,它是查出所有分类,只不过这是一个分页查询,我们呢,现在需要把它以副词方式组合起来,那我就给这个方法写一个tree,那我们的功能呢,就是查出所有分类以及子分类。以及。
03:22
子分类,然后呢,以树形结构,树形结构组装起来。好,我们就来做这个功能,那这个功能呢,我们把这些先删掉,请求参数呢,我们不需要什么参数,现在就是查询所有,那好把这个去掉,我们调用分类的service,分类service呢有一个方法,首先呢,List,这就能帮我们查到所有的分类,但是呢,数据库所有分类拿来,我们要组装成副子结构,所以呢,我们希望category service里边有一个方法list with字tree,它呢能一次性帮我们查出所有,并且呢组装成我们树形结构的,那最终呢,还是返回我们整个分类的这个数据好,那这一块呢,就写category entity。
04:18
我们来返回这些数据结构,那最终呢,我们把这些数据结构一返回,那我们就在这写一个data,这是最终的返回数据。我们就来生成这个方法,Al创建出这个方法,首先呢,它创建到了categories service这个接口里边,那这个接口的实现类呢,还没有这个方法,我们接下来给实现类里边也加入这个方法,好al in添加对于这个方法的实现,那这个方法呢,功能就是查出所有分类。首先第一步要查出所有分类,然后呢,第二步我们要组装成,组装成咱们这个副字的树形结构。
05:10
好,那我们先来写第一步查出所有分类,那我们要查哪个表,就相当于要用逆向生成的哪个do,那在这个do里边呢,就有分类do,那所以我们的写法呢,就是can。Cat gory do,我们把它呢注入进来,这是这时呢我们最原始的写法,当然最快的写法是我们这个service已经继承了它的这个service employment,这个employment呢,里边已经加入了泛型的这个category的实现,所以我们在这个employment里边有一个叫base member,这个base member呢,其实就是我们真正的泛型指定的这个member,也就是我们的category do,而我们可以注入它,你也可以直接在这儿拿到base member,诶这就是categy do一模一样的,包括我们在调方法的时候,我们看到这块泛型都是category entity,好,那我们就用base member,哪个服务的base,那就是操作哪张表的,那就是操作这个实体类指定的表的,那现在要查所有,那直接点一个。
06:23
Select list,我们查出所有,这个所有呢,由于我们没有任何查询条件,所以我们在这给他传一个now,没有查询条件,那就是查询所有,这样呢,直接给我们返回所有的分类数据,我们将分类数据呢返回,我们先不组装成附子结构,我们先来启动商品服务,来测试一下功能,好,我们来启动起来。我们先来看我们controller的第一个功能,我们product category list。
07:01
好,等我们商品服务启动起来。好,我们商品服务呢,是在1万端口启动,那前面这些报错呢,都是跟我们NAS相关的配置有关,我们暂时可以先不用管好,我们现在来访问1万端口,我们指定的请求local host1万端口,然后呢,我们访问我们商品服务,我们商品category。商品category里边的list tree。我们回车。现在呢,我们发现这已经查出了所有数据,我们这些数据呢非常多,但是我们并没有把它组装成副词结构,那我们接下来就将它组装成副词结构。我们来重新编写一下我们的这个商品服务功能,在这一块呢,组装附子的树形结构,那组装附子结构呢,我们要做的第一步,好来编写一下我们要做的第一步,当然首先呢找到所有的一级分类,那这个所有分类数据呢,我们全体全部查出来了,我们只发了一个circle狗,那为什么想要找一级分类,我们就在这里边来找,怎么找呢?所有的一级分类最大的特点就是他们的负分类的ID是零,那么二级分类呢,他们各自都有自己的负分类ID,三级分类也各自都有负分类ID,那只有一级分类呢,它的负分类ID是零,所以呢,我们来挑出这些我们使用呢stream API,好,我们直接点一个stream,我们filter进行一些过滤,这个API里边呢,我们是这么来写的,箭头函数,小括号,间括号,大括号,由于呢,我们现在要过滤每一个元素,每一个元素呢,都是这个cat。
08:47
气体那么过滤的。条件就是我们集合里边每一个元素都有一个它的负分类的ID,如果这个负分类的ID等等零,那说明这是一个一级分类,把这些一级分类呢,最终收集成一个集合to list,好,我们使用stream API先把它收集过来,这个呢,我们就叫LEVEL1MENU。这是我们。
09:18
一级的所有菜单,当然我们说这个最简化的写法,由于它只有一个参数,小括号可以省略,而且呢,这个只有一条语句,它是返回值,大括号和我们的return可以省略,我们把这个分号呢也删除掉,那现在我们这个就写好了,我们先来测试我们能不能把所有的一级分类挑出来。把一级分类挑出来以后呢,我们再为每一个分类设置好它的子分类。好,我们来稍等启动。这块的报错呢,我们一会儿再配置好,好我们先不用管。我们还是访问1万端口,我们直接来刷新我们这个之前的数据刷新,诶我们发现呢,这还是所有数据,哎,那是由于我们这一块没有写返回值,那先将所有的更菜单我们都先返回。
10:14
好,重新启动,我们来等待一下。我们现在继续来测试,我们来刷新一下。那现在先来获取所有的一级分类,好,现在呢,都获取到了,接下来呢,再来找到每一个分类的子分类,那要找子分类呢,我们的这个entity里边,我们希望多写一个属性,这是一个什么属性呢?我们来写上list,它里边呢,包含所有它的子分类category entity,我们就叫丘疹。这是它所有的子分类,当然这个子分类呢,不是我们数据表里边的相关属性,所以呢,我们需要标注一个注解叫table field,我们的表里边的属性,这里边呢,有一个叫exist,是first,哎,这个东西呢,在数据表里不存在,这是我们加的一个自定义的属性。
11:10
接下来我们要做的就是将当前菜单的所有子分类都保存在这个属性里边,来重新编写我们的这个service方法,在这儿呢,收集之前我们还可以改变菜单里边的相关属性,我们可以使用map,诶,我们stream API里边提供的map映射方法,将每一个菜单呢重新我们来改变一下,好,每一个菜单我们写在这儿,我们还是箭头函数,那最终的做法呢,就是我们将当前菜单的子分类给它保存进去,如子分类呢,我们写好了,最终将当前菜单再来返回过去,那我们就相当于把当前菜单改了以后呢,把这个菜单重新返回,再收集成这个list,但所有的子菜单在哪里,我们呢,可以写一个递归的方法来找到每一个菜单的子菜单,那么在这呢,直接来写一个方法,这个方法呢。
12:11
返回category entity。这ndna呢,我们就叫get childrens,哎,Get children获取某一个菜单的子菜单,当你把当前菜单给我传过来,Category ntt,我们这个NT和你要从哪里获取它的子菜单,那我们所有的菜单数据,我们也让它传过来,传上两项,这是当前菜单,诶,我们这个root菜单,这是所有菜单哦,我们在这里边呢,找到这个菜单的子菜单,那怎么找呢?我们来先return一个,那那我们最终希望的就是调用这个方法,将找到的当前菜单的所有子菜单给它设置进去,当这个方法呢,还要多传一个参数,我们是来找menu菜单,在这个里边找到它的子菜单来重新设置进去,包括呢,我们如果把副菜单找到了。
13:14
其实副菜单呢,还要排序好,我们这个排序呢,我们只只需要用最简单的方法,我们还是先不collect,我们map呢已经映射好了里边每一个元素,我们接下来继续调用点salt。好,我们给它进行排序,排斥箭头函数,那排序呢,就是我们当前已经映射好的菜单,那在这一步呢,将每一个菜单子菜单都找到,现在呢,我们给这些菜单要来进行排序,那如何排它肯定呢,传入一个前面的菜单,传入一个后面的菜单,两个要进行对比,那最终返回对比的结果,我们每一个菜单呢,都有一个叫get sortt这个方法,那这个方法呢,我们就是它的排序字段,我们让呢第一个的排序这个顺序,我们减去第二个的这个顺序,给它们一个最终的这个升降序的值,那他排完序以后呢,我们最终将所有的数据都收集到这个list里边,然后在这来做,那所有呢,最终所有的方法都集中在这儿,们来可以递归查找所有菜单的子菜单,那怎么找呢?这就是当前菜单,我们要找它的子菜单。
14:29
首先我们还是来从这里边进行过滤,哎,我们还是filter filter呢,我们来过滤我们这个菜单,那这个过滤的办法呢,那就是我们想要让当前菜单的我们有一个叫parent cid,它的负ID,如果等于我们指定的这个菜单的ID,那说明当前菜单就是它的子菜单,所以这是我们的过滤方法,那整个过滤完了以后呢。
15:00
我们来收集到这些所有的菜单,To list。那其实呢,整个这个菜单就是我们要用的子菜单,但是实呢,这个子菜单,同样每一个子菜单呢,有可能还会有子菜单,包括呢,这些菜单还是需要排序的,所以呢,我们还是我们之前的方法,我们继续点map,我们将这些菜单里边呢,每一个东西呢,我们重新来映射一下,那现在需要怎样映射呢?我们为每一个当前的这个菜单,我们还是找到它的子菜单,我们调用set children方法,那如何找呢?还是这个调用get childrens,为哪个菜单找为当前的这个菜单,在这个里边找到它的所有子菜单,那我们来找到这个以后,把当前菜单进行返回。同样我们这些菜单还是需要排序,点sorted我们来进行排序,那如何排序呢?我们还是把我们的当前菜单传进来,我们这个排序呢,可能前边的菜单还有后边的菜单,我们来写一个箭头函数,好,那么最终按照排序的规则是前面菜单的sortt减去后边菜单的salt字段,诶,这是我们排序的值,那最终。
16:31
找到他的子菜单,排好序以后,把它们收集返回,这就是我们的子菜单,我们来备注一下,那在这呢,就是来找到子菜单,特别是这一块呢,是一个递归找法,我们在这儿找子菜单的时候呢,会重新进来,进来以后呢,继续如果有子菜单继续来找,找到以后呢,那在这儿再来进行排序,诶这是我们第二个菜单的排序。
17:01
至此呢,我们这个方法就写完了,我们最终呢,返回到这个LEVEL1里边就应该带它的所有子菜单信息,我们来测一试一下,重启。我们最终实现的效果呢,就应该是我们只发了一个SQ语句,查出所有菜单,再利用递归的方式,我们来组合出附子菜单。好,我们现在来刷新刷新。我们发现呢,这有报错,那报错的原因我们来看一下这一块的原因呢,就是在这空指针异常,因为我们有可能返回的这个sot,它可能为空,所以呢,我们可以在这处理一下,如果这个sot能在这来写一个小括号,小括号。这个sot字段呢,现在默认是一个inte,它有可能为空,如果它等等,那等等空吗?如果等等空,我们就给它给一个默认值是零,否则就用它自己的值,包括我们第二个也一样,它有可能为空,我们来判断一下它等等空吗?如果是空,我们就用默认的零,否则用它自己的值。
18:19
复制过来,那这一块的写法是这样,下边也一样,CTRLC,我们在上边这一块也是这样,CTRLV,然后我们来重新起来。好,我们现在来测试一下效果,我来刷新,我们看到呢,这已经有结果返回了,那这个数据到底对不对,我们来F12打开控制台,我们重新让他发一个请求,我们在这来pre you来看一下,在这呢,我们先来看data塔里边有这么多的数据,零到A20个,这个先呢是我们一级分类,那每一个一级分类里边呢,求证里边,那应该是我们二级分类,点开这个里边呢,有12个,那每一个二级分类里边还有三级分类,我们再来点开求证里边,诶这有五个,每一个三级分类里边呢,再也没有它的子分类了,那我们这一块呢,就查询的是正确的,包括呢,我们还会有排序相关的信息,如果我们数据库里边相关的排序字段变了,那它它的顺序肯定也会发生变化,比如我们来举一个例子,我们这个顺序呢,让它变为一,它变为二,它变为三,那剩下呢都是零,那都是零的话呢,零的优先级。
19:34
更高了,剩下的就是它的优先级高于他,再高于他,我们来测试一下,我重新发一个请求,好看一下返回的这些tree,那我们来看到呢,剩下的我们编写的123这三个排序,一所有的零在最前面,那一大于二大于三排序字段也都OK,那至此呢,我们这个功能就先编写完了,下一节课呢,我们来编写后台管理系统,我们进行联调。
我来说两句