00:00
前面我们编写了属性分组的一些基本功能,接下来我们对商品系统里边的其他接口进行逐一联调测试,并新增一些有用数据。首先在分类维护里边,我们将原始的数据呢导入进来,这些就不要了,我们打开我们原始数据,在基础篇文档我们的代码circlel里边,我们将分类的原始数据ctrl a ctrl c,然后呢,我们粘贴到我们这一块,选中PMS。好,执行成功,那我们这一块的数据呢,就可以是原始数据了,我们的点分类维护在手机,手机通讯里边,那都一切正常。接下来我们来看一下品牌管理,在品牌管理我们先来测试查询功能,特别是我们这个模糊查询,比如我们要查一号品牌点查询,发现这一块呢并没有查出来,因为这个查询是我们使用逆向生成默认的,所以我们要将这些查询添加上我们自己的功能,包括我们在封页的时候,我们发现这块封页的统计数据是错的,比如共零条,原因是我们使用马贝斯plus要进行封页,我们需要引入封页插件,具体的引入方法呢,我们可以参照一下my plus的官方文档,它这一块呢,我们也往下翻,有一个分页插件,要想使用分页插件,我们spring boot的方式就是给容器中放一个interceptor,那我们也来配置一下,先来到我们product里边。
01:27
我们来到man里边,好,我们在这呢创建自己的一个配置文件,我们也出创建一个我们自己的MY贝蒂的配置,我们将后来的配置我们全放在config文件夹下,我们就叫my conig。首先我们来标注它是一个配置类at configuration,然后呢,我们要开启事务功能,我们首先使用enable transition management,这是开启事务,开启事务这样我们的方法标了事物注解就可以使用事物了,包括呢,我们也像他一样,让他map sc扫描我们这些map接口。
02:07
好,来加上map sc来给它指定一下我们接口的位置,他们都都在这个do包下把这个reference复制过来。好,接下来我们在这要引入分页插件,引入分页插件,这分页插件呢,我们就直接复制过来,Page intercept好复制。给容器中加入它来导入这些依赖,导入依赖包括这个intercept呢,自己也可以调整一些设置,比如如果分页请求的页码大于最后的一页,如果我们调为处,它默认就回到第一页,调为false,那它就会继续请求要到空数据,那我们就可以给它调成处啊,如果你转一个非常大的页,那就直接回到第一页,包括这一块每页最大限制数量,默认呢,每页限制500条,也有负一不受限制,我们也可以给它调整,每页最大受限1000条。
03:05
有了分页插件以后,我们先来启动,那我们分页功能这一块就应该没问题的,原来是零条,我们现在看它能不能统计正确。我刷新进行测试。好,我们发现这一块四条就统计正确了,分页调整好了以后呢,接下来我们再来修改品牌的模糊查询功能,我们来到品牌的接口,找到controller brand controller,我们在这list查询的时候corre page,好,点开默认的这个wa呢是没有任何条件的,它就是检索所有我们现在来获取到K,我们来要进行模糊查询,我们就palms点一个get k,由于我们在查询的时候,如果我们带了字段,比如我们来写了一个AAF12,我们在这查询的时候,那在这呢,K就会有一个叫AA,所以我们找到这个K的值,我们找到这个K的值,而且这个K呢,有可能会作为我们的这个主键ID,比如我们输的是一,那有可能也搜的是这个ID为一的,所以我们找到这个K以后呢,可以先将它转为string。
04:14
强制转换我们来判断,如果说我们string uus.is empty,我们传过来的这个K不是空的,它有值,那说明页面要进行模糊检索,那模糊检索呢,我们就将这个检索条件我们先放到上边。要进行检索,我们的这个vaper里边就要多封装一些条件,首先我们就得封装上我们的ID是这个,或者我的我们的名字模糊匹配这个,你们就点一个E。ECO呢,首先是ID。来找到品牌表里边儿。打开。首先是品牌的ID,我们这一列品牌的ID等于我们指定的值。
05:04
等于我们指定的值,或者我们点哦哦,什么呢?Like我们的名字这一列。是一个模糊匹配规则,好name传过来。模糊匹配的值呢,就是这个K,我们重新启动进行测试。我们来进行刷新。测试模糊检索,我们现在这有AA小米,哈哈,我们就来搜索带A的查询。诶,我们发现这两个带A的没问题,包括我们搜索四号品牌的,没有那一号品牌的走这一块呢,都是检索正常的,我们把这个条件清空,现在查询所有。我们可以将这些值呢全部删掉,批量删除,确定。我们新增一些有用数据,比如我们来新增品牌,华为,我们的品牌logo地址,我们点击上传。
06:01
来到我们。桌面我们资料里边有专门的这些图片,好,我们来找一个华为的logo。好,上传成功,那我们来介绍华为。搜检索首字母H,比如排序给个一点个确定。好,这个是没问题的,我们再来新增。那测试数据我们就新增完成了。包括修改这些功能,我们以前测过都是正常的,当然在品牌里边呢,我们还多新增了一个功能叫关联分类,当然要使用这些功能,我们要求大家最终把我们写的这个前端代码复制到自己的项目里边,这有一个代码前端直接把models里边这两个复制放到自己前端项目的这一块来打开。在views里边,我们在资源管理器中显示,将自己views models里边呢,这两个文件夹整个替换,你可以直接粘贴过去,那我给大家的代码呢,大家就导入进来了,这些新增的功能就可以进行联调测试。接下来我们编写关联分类功能。首先在我们电商系统中,每一个品牌都应该有它所属的分类,比如华为、小米、OPPO,他们都是手机分类下的品牌。
07:29
但是呢,一个品牌不只会关联一个分类,它有可能还会有多个分类,比如小米,它既造手机,它又关联手机分类,它又有电视,那还关联了家用电器的分类,包括还有其他的杂货,所以呢,我们这是一个品牌会对应多个分类。而且呢,一个分类下一定也会有很多个品牌,那无论从哪一端往过看,都是一个对多的关系,所以说呢,这就是一个多对多,那多对多我们在数据库中一般就会有一张中间表,比如caterorry brand relation,它来保存哪个品牌关联了哪个分类,所以呢,我们应该编写第一个接口F12来打开文档,首先如果我来点击关联分类,我们在network中我们会发现我们会发送一个请求,这个请求叫product category brand relation catalog list,它要查询我们当前品牌关联的所有分类,而且如果它还没有关联,我们还可以新增关联,我们在这儿选中一个分类,我们接下来点击确定,那么就会保存过去,我们可以看一下save,那同时又会发请求去来。
08:42
保存我们商品分类的关联关系,那这块呢就会有两个接口,这个接口呢可以对照我们接口文档来进行编写,比如商品系统里边,我们在下边儿有。获取我们这个品牌关联的分类,就是这个接口最终会返回当前品牌关联的所有分类的ID和他的名字。请求的时候呢,会传递一个请求参数,叫brand ID。那好,我们先来编写这个接口,来到我们的后台,分类与品牌的关联control,我们就是product category brand relation,接下来需要有一个路径叫catalog list。
09:20
好,我们在这呢,复制一个CTRLCCTRLV,我们的整个路径呢,叫t log list,我们把方法名呢也变一下,而这个请求呢,按照接口文档我们会传递一个分类的ID,包括大家也可以去来分析我们整个前端发出的这个请求,我们看到他发请求的时候呢,也会带一个品牌的ID,所以我们在这儿需要一个请求参数,它是浪类型的品牌ID。我们在这标注一下获取请求参数brand ID拿到以后呢,我们最终会返回一个list,类型的什么呢?我们来看一下,在接口文档中主要返回当前分类的ID以及分类的名字,而这些呢,我们发现这张关联表里边儿也保存着当前品牌的ID,对应了哪些分类,包括分类的名字,这都是有的,所以我们相当于直接来查这张表就行了。好,那么最终希望就返回这张表里边的这个关联关系这个实体类,我们来到controller返回一个list。
10:27
那么最终返回的data呢,我们就使用它的这个service,第二我们要查询一个集合,我们调用list方法,里边要传入我们的查询条件,那就是corry rapper,那这个vaper呢,当然也是来查询这个实体类的。那这个waper的查询条件,我们来构造一下,它这个查询条件呢,主要就是品牌ID要等于我们指定的值,那就echo,咱们这个中间表里边儿会有一个品牌ID。等于我们传过来的值。
11:02
Brand ID。最终将查出的这个数据返回,而且返回的这个字段叫data,我们来看一下,在接口文档中它就叫data,那我们的获取当前品牌关联的所有分类列表功能就写完了当前品牌。关联的所有分类列表功能我们就写完了,那为了有效果,期间呢,我们同时再来写一个保存,而且这个请求是一个get请求,所以我们一般这么写,我们给它写精确Y6是它我们使用的method允许的请求方式就是request method里边我们来指定它必须是一个get.get那每次这样写呢,太麻烦了,在spring mvc中呢,有一个新的注解叫get满品,那get满屏呢,相当于是request满品get版。
12:03
那以此推理,它就有post mapping,处理post请求的还有delete mapping put mapping等等等等,所以我们现在呢,用简写方式get mapping直接将路径传递过来。CTRLC复制过来这个就不用了,包括get man点开我们就会发现它的上面呢有一个request man man是get的这个注解。接下来我们来编写保存功能,这个保存呢,那就是保存我们当前品牌的ID关联的这个分类信息,那么这有一个新增品牌与分类的关联关系。那在新增的时候呢,会传入品牌ID以及分类的ID,包括我们前端的这一块,我们来测试一下,我们在新增选中以后,我点确定发送save请求,会给我们传品牌ID和分类ID。那这个呢,我们在下边也有也有一个save方法,这个save方法就是来收集里边有品牌ID、分类ID,当然还有其他的字段,只不过其他字段我们不传那就无所谓了,包括这个路径这一块,我们来看一下,它确实是product category relation save,那就是这个方法,那是这个方法呢,我们就来处理一下,我们不能用原生的save,如果用原生的save,由于我们前端并没有传品牌的名字和分类的名字,所以在数据库里边呢,不会保存有品牌和分类的名,虽然我们说这两个名字我们在这儿可以不涉及,也可以用品牌ID去品牌表中查和分类ID去分类表中查,但是每次都这样做关联查询,会对数据库的性能呢有非常大的影响,咱们电商系统设计里边,对于大表数据我们从不做关联,我们哪怕分布一点一点查,我们尽量少用关联,所以我们在设计的时候呢,添加了两个冗余字段,相当于让我们要保存。
13:56
从品牌ID的时候,把品牌的名字也保存着,和分类的ID,分类的名字同时保存上来,所以我们这个save方法我们得重新处理一下,在这调save之前,我们得先确定这个品牌的ID,品牌的名字对应的都是什么,所以我们来自己来写一个方法,Save叫detail,保存详细细节,我们创建出这个方法。
14:21
来添加上它的实现,在这个save detail里边呢,我们主要是kind relation里边,我们要获取到它的品牌ID和它的分类ID,根据这两个我们要拿到品牌的名字和分类的名字,好,我们先把这两个获取到,接下来我们查询品牌的名字和分类名查询。查询详细名字。那这个查询呢,我们就需要用到品牌和分类的这两个do,所以我们就来注入品牌操作品牌的do,好,我们就直接注入do,包括我们来注入调用分类的do category do好来owaar,我们首先来查出我们品牌的ID啊。
15:14
我们SELECT8ID,我们按照这个品牌的ID直接查到品牌的详情,同时再按照分类的ID select8id查到分类的详情。然后将他们的名字最终设置到这个关联关系里边,这个关联关系里边已经有了两个ID字段,再来设置两个名字,一个是品牌的名字,点get name,另外一个是。分类的名字点set category category entity.name。那当我们这个里边所有的字段都设置好以后,我们调用保存。那就是用自己的这个doo,那相当于category brand relation doo,那要用自己的doo,那就直接this,点它里边有一个base member,那就是自己的do,那就算不用base member,我们这个this啊,就是当前service,当前service呢,也有cell方法,那直接调用当前service自己的save方法。
16:20
将完整的信息保存,那么这两个接口就写好了,查询它的关联关系以及保存它的关联关系。我们重新启动一下商品服务。我们现在来进行测试刷新。首先来打开将关联分类,这呢,由我们原来测试的这两个不对的数据,没有新增品牌名和分类名的,我们可以把它移除掉,然后呢,我们再来新增关联,我们选中一个分类,比如它来关联手机类,我点一个确定,诶那我们华为这个品牌名,它关联手机分类,包括我们再来新增,我们可以关联家用电器,大家电,平板电视,好,我点确定,包括我们来看数据库。
17:09
刷新,那我们为华为这个品牌呢,就关联了两个分类,那这块我们就写好了,点击确定,包括我们刚才看到的这块移除功能,我们都是使用它默认的,我点击移除,它去发送delete请求,删除他们的关联关系,会发送当前关联关系的ID,好,我们重新给他新增上。平板电视好确定。那品牌的这个接口呢,我们就调试完了,那现在呢,我们还有最后一个问题,我们为了方便检索,当我们点关联分类的时候,我们会将当前品牌关联的分类名以及品牌名都会查出来,这个查询呢,我们并没有做连表,我们是直接在中间表里边进行了冗余存储,但是万一这个品牌名或者分类名在真正的品牌表与分类表里边进行了修改,那我们这一块呢,就需要数据同步过来,包括我们系统里边后来会有非常多的冗余设计,要保证这些数据的一致性,我们就需要修改业务代码,在业务里来保证他们的一致。比如来到我们的品牌controller,我们在这修改品牌的时候不能直接上来只改一张品牌表就行了,所以我们还要进行判断,比如我们就叫update data,我们来更新细节,但是这个细节更新呢,我们不只要跟品牌表,所有冗余存储的我们都要更新我们。
18:34
在这来判断一下,我们在这儿必须呢考虑保证冗余字段的数据一致,那怎么保证呢?首先我们先更新自个调用this.update by ID,我们先把自己表里边的品牌更新掉。其次,我们再来判断,如果此次更新的品牌里边有更新品牌名字strings.is empty。
19:04
它的这个品牌名不是空的,点get。Name。如果品牌名不为空,那其他表里边也会保存品牌名,所以说我们要同步更新。其他关联。表中的数据。那此时我们就需要。拿到category brand relation service,我们自动注入它,我们希望它里边呢能有一个方法,那动态更新我们品牌的信息,所以我们在这点update brand。来更新我们品牌信息,当然要更新的是什么?在中间表里边儿,就是所有这个品牌ID的全部得更换品牌名字,所以我们只需要这两个字段,那么在这设计的时候呢,就可以不用传对象,比如简单的就来传两个字段,一个是我们品牌的ID,另外一个是我们此时要更新的品牌的名字get name。
20:09
那不仅有我们中间的这个关联表要更新这个品牌信息,包括后来我们其他表都会维护这个冗余信息,所以我们在这儿先来放一个todo更新其他关联,我们后来再写上,我们先把这个方法创建出来。在这个方法里边呢,我们添加上它的实现,主要更新关联表,当然此次更新我们是这样更新this.update我们要更新的数据以及这个条件都是不一样的,所以我们利用第三个update方法,能传入自定义的waper条件和我们要更新的数据,那这个数据呢,我们先来创建一个中间的这个关联关系实体类,好,我们把这个创建出来。把这个关联关系里边呢,我们就放上两个字段,第二,第一个set brand ID设置品牌ID是它还有我们品牌的名字,点set品牌的名字,我们是这个。
21:11
那我们要更新的就是它,但是我们要更新的条件,我们用一个update waper,这是我们的更新条件,当更新条件用它查询用corry wrapper update呢就用update waper,那更新条件是什么?我们必须是E口,只要所有这些品牌ID是我们指定值的,那就是品牌ID。必须等于我们指定的这个值。这是我们的更新条件,而要更新的字段,那就是我们带了哪个字段就更新哪个,我们现在只带了name,我们这个方法写好,但是我们现在假设先不重启,我们来测试没用这个功能之前的效果,比如我们在这修改华为的时候,我们将品牌名改为华为一,我点一个确定华为表呢改了,但是在关联分类里边品牌名还是华为,所以这就是有问题的,而我们加入我们新写的功能重启。
22:11
我们现在来测试一下。我现在来修改,我们把这个华为一,我们改为华为二,来点一个确定,在这更新成功以后,我们看关联的分类里边,诶,它都叫华为二了,我们重新给它改回去。还是华为,那我们品牌也一样,那分类呢也是一样的,我们直接来到分类的controller里边,从它对分类的修改入口,我们直接对它进行一个统一更新,比如我们现在换了我们就叫update caca,我们进行级联更新,怎么级联更新呢?好,我们创建出这个方法。我们要极端更新它的所有数据啊,创建出来。这个方法的功能就是集连更新所有关联的数据,首先我们要更新自己this.update要更新自己,我们都是按照ID去来更新的,好,然后呢,接下来调我们的几点更新,除了更换自己,我们还要更新关联表里边的,我们将关联表的这个service拿过来,Category brand relation service。
23:20
好,我们来直接自动注入at一个owa,我们希望这个里边呢,也有一个方法叫。Update category。还是传入我们三级分类的ID,第二,Get我们的ID,以及传传入我们要跟的最新的名字get name,创建出这个方法。添加上这个实现。我们调用自己的do,比如我们点一个base member,直接有一个自定义的SQL语句来支持这个功能,那么调用base,我们来update category,传入cat ID以及name。
24:10
我们直接给best member里边创建出这个方法,而且这个方法呢,会关联我们马贝蒂斯配置文件里边的一个方法,那我们装了马贝斯X插件,那它这就会有一个快捷的件,我们al in,这叫generate statement,生成我们这个circle,我们直接点一下,它现在就会在我们指定的这个do里边帮我们来生成这个,那我们的更新语句我们来写一下。那就是update set这张表,Set,我们的分类的名字等于现在指定的名字。条件呢,那就是where,只要分类的ID是我们指定的ID的,等于什么?那好,这是我们的SQL语句复制过来CTRLC。来到我们这儿,将SQL语句粘贴过来。
25:01
单这个分类的名字和分类的ID,这是从我们这个方法里边取到,我们看我们这个方法它有两个参数,那我们说以后买贝声明的这个member接口,如果有两个参数,一定推荐大家使用an p为每一个参数起一个自己的名字,比如我们就叫cat ID这个呢我们就叫name。否则你想要获取这个参数的值就很麻烦。你要。到了F大括号,P0P1之类的,好,我们现在呢,就可以用我们自定义的名字,那ID,那就是井号大括号,我们的cat ID那这一块呢,就是井号大括号。看他name。我们把这个分类的名字复制过来,诶,这直接叫name。我们用了两种不同的方式做了刚才这两个事情,品牌我们用了update wrapper,我们这个直接用了自定义的SQL语句,好,我们现在整个重启。
26:01
来完整测试,我们刚才修改品牌,整个是好的,我接下来测试修改分类,比如我们在手机类里边来修改一下,把手机叫手机一,我点一个确定。来看一下我们在品牌关联里边关联分类,诶这一块呢,也已经有手机一了。我们重新给他改回去。以后所有我们系统里面的冗余字段,我们都可以这么来处理,当然最重要的就是我们的这个方法,我们来看这CTRL调用我们这个方法,不仅更自己还要更新几连的,那整个这个呢,这是一个transition的,这是一个事物。而且我们只有开启了这个事物注解,我们这个事物才在这儿可以使用,但事物的详细配置细节,我们后来还会说,我们为这些方法都来统一加上事物。包括品牌的这一块,在这更新详细细节的时候,好,我们来也给他加上15,那现在呢,我们整个的品牌管理这一块,我们就算调通了。
我来说两句