如何通过前端的头信息来编写商品信息,实现商品的通过关键词查找等等功能,并且通过包装好的结果集进行返回
我们点击品牌管理,然后出现下面的界面:
我们可以看到,类别信息都已经有了,而且控制台出现的这个信息告诉我们它没有对应路径,也就是没有分页结果集来进行响应,所以我们需要建立一个分页结果集,但是这个分页结果集要建立在哪一个模块上呢?如果是建立在服务端模块行吗?不行,因为只建立在服务端的话,那如果其他模块也需要怎么办,事实上,像会员管理,销售管理都需要这个分页结果集,他们都需要对分页结果做出一个显示,所以既然是大家都通用的模块,那么我们可以把它放在网关那里让大家都可以调用。
所以我们应该建立这个分页结果集呢?
这个是我们在网关模块建立的分页结果集,可以看到我们封装的三个对象,一个是页面数。另一个是页面总数,还有一个就是商品的结果。
我们封装了这个结果集之后,我们就可以在各个模块去调用这个结果集。
接下来我们就要用get set方法。
然后我们可以看看前端这里。Id对应的是id,名称对应的是name。就像上图所示,一个个对应。
可以看看这里头部对应的数据模型是头部,然后items。对应的数据模型是brands。这里描写了就是你是什么组件就对应什么样的数据模型。他头部这里的数据模型已经在前端页面写好了。剩下这个商品的数据模型需要我们后台帮助去实现。
在这里你可以看到商品的数据模型是一个集合,这就说明需要我们用后台。去连接这个数据并且响应数据给他。
我们可以看到这里有个对象。
这个对象是分页信息对象,也就是像刚刚商品模型一样,是一个空集合。
那我们应该怎么样在后台实现这个功能呢?这就需要我们在刚刚的网关模块里面的分页结果集里面去编写方法。因为我们的分页结果,其设定在网关模块这个模块,很多其他模块都可以拿来调用。只要我们设定好他了。那其他微服务都可以随意调用这个分页结果。
再来说明一下这个模型。其实只要你去定义他是这个pagination模型之后,网页会自动生成关于它的属性。比如说按照id去排名。或者分页。这个都是会自动生成的,不需要你去配置。
分页参数都在这里了,你不需要去配置任何东西,只需要建立这个数据模型,它就会自动配置。
所以你只需要建立一个空的集合就可以了。
再看看这个数据模型,他是干什么的呢?我们刚刚之前定义过他的后台方法,这个就是页面的总条数。也就是说你的商品有多少页,这由他来定义的。你的数据库的量有多少就会在他这里显示出来。
然后它的对应数据就显示在这里。目前设置为零。
还有这个数据模型,这个数据模型是是是什么意思呢?就是你在家在商品的时候显示了进度条。你设置了这个之后,你再点击商品加载的过程中就会显示这个进度条。显示进度条有一定好处,就是客户在等待的时候他能知道这个进程加载到哪里。会能让客户了解情况。所以这个也是很重要的。
我们需要在前端页面设置的这个进度条,我们需要给他一个true,如果我们给他一个true,就代表开启进度条。如果返回一个false,就是关闭进度条。
我们可以看看商品模型是怎么渲染的。,首先看看props,这是个遍历方法。能够把各个商品都轮一遍。遍历方法就像一个循环集,以前我们用遍历方法时,多数是用在浏览每一个数据库的商品的时候。这次被前端这里用来遍历每个商品。看下面我们渲染的id名字。还有图片首字母。然后这些都有在数据库有对应的信息匹配。
这里注意我们在小数点后面必须要加属姓名。而且要和数据库对应的属性名。这样才能把数据库的模型拿来渲染。如果名字出错了,那可能渲染失败了。
我们点击的页面之后,它就开始执行渲染后的方法,也就是查询这个数据。这个时候他就会去数据库里面找对应的数据。
然后这个是他的执行方法。他设定一条路径。去发起请求,然后添加了各种搜索条件当前页之类的信息,赋值给key,page之类的,然后把items赋值给商品
这里需要说明的是,他就是把这种商品绑定给结果集。resp是响应的意思。响应的数据。也就是结果集。然后绑定给后台的对应模型,绑定完成后也就是完成赋值了以后,他就把加载状态改成关闭。
其实最主要的就是先看前端页面是怎么编写的,它是把商品结果集赋值给哪几个数据我们需要看它赋值给哪几个数据,再把这几个数据拿回来。引用到我们的后台当中,然后再去编写业务逻辑。比如说分页结果集这里,我们需要编写的是分页多少,总页数多少,还有返回一个什么商品对象。这些都需要我们自己去编写业务逻辑。具体是怎么编写的呢?首先我们需要封装方法。把这三个对象都分装了。并且添加get set方法。然后我们就要去连接数据库。。通过数据库的信息,然后去编写这个业务逻辑。具体该怎么做,我们接下来会讲到。
如果我们不喜欢他这个头信息,我们自己是可以修改的。比如在这个text里面修改,修改他的名字。你想要换成什么字都可以,比如把名称换为名字或者商品名都可以。还有他的格式。你都是可以在这里修改,只要你找到前端对应的商品编写页面,你就可以拿去修改。
分页结果集不是什么页面都可以加的,你首先要看。你点击了组件之后,他返回一个什么结果?他如果返回的结果里面有显示页面的数量的话,那就是分页结果集。如果没有返回页面的数量的话,这就不是一个分页结果集。所以你需要一个list。编写的业务逻辑也是编写list的返回结果。
因为我们要返回商品信息,所以我们要针对商品封装一个对象。因为我们在网关部分已经编写了分页结果集,然而,分页结果及处不仅有分页信息,而且还返回商品,具体是返回商品的什么值呢?我们需要再去编写一个商品的封装类。如果不去编写这个商品的封装类的话,到时候在页面上显示的商品信息就会错乱。或者根本不显示。那有人会说为什么我们不在网关里面直接去编写这个pojo,因为那是我们的网关方法,网关主要用来拦截信息审核信息。还有就是配置过滤器。因为我们刚刚的分界结果集方法有很多微服务都需要,所以我们必须写在网关那里。但是网关那里不用配置数据库。他只是写一个方法。配置数据库的类还是在我们这个接口类。所以我们需要在这里配置商品的信息封装方法。在这里配置好后连接数据库,然后就会在页面显示出我们的商品信息。而且其他微服务显示商品信息的格式可能不一样。我们在接口类配置的商品信息是id名字,图片和首字母。其他微服务配置的信息可能不是这些。有可能是id名字,logo和价格。所以我们在接口配置好,这个是为了让商品管理这个微服务可以先去调用网关的方法,再去调用接口类方法。然后实现商品的分页显示以及商品信息。
这里可以看到id和下面那个注释,是表示主键的意思。还有首字母的Character,这个代表的是一个字母的方法,也就是说你用了这个方法的话,你只能写一个字母。所以特别适合我们去封装首字母。
然后我每一次创建实体类对象的时候都是在接口模块去创建这个实体类对象。至于编写他的业务逻辑都是在服务模块里面去编写业务逻辑,这是为什么要这么做呢?因为实体类的话,我们单独写在接口模块里面是方便其他微服务去调用。然后把他的业务逻辑分开写在服务模块里面。这样也可以去实现他的业务逻辑。我们放在接口类里面的实体类有商品信息的封装,而且总共有两个都是商品信息的封装。他们都是对应不同的功能组件里面的商品信息封装。都是由服务模块去实现它。如果前端有个商品信息需要我们去显示。我们应该如何去编写这个业务逻辑去实现它呢?首先我们需要建立一个实体类,写完这个实体类后,我们就需要建一个mapper方法,用这个mapper方法去继承jar包里面的mapper方法,为什么要继承这个mapper方法呢?因为这个方法就是操作数据库的方法,比如操作数据库的增删改查。之后我们就在service方法里面,去封装这个mapper方法。然后最后我们在controller里面调用这个service方法。这就是一个业务逻辑的写法。
这里需要注意一点。就是你的mapper方法要在引导类那里面进行扫描。而且你继承的mapper方法是一个泛型,你需要传入实体类参数
然后我们这里注意service方法跟mapper方法都不需要写其他东西,都是由controller来写。
我们可以看看这个。api/item都是网关里面的地址,后面的brand/page就是可以让我们后台进行截取的地方,前端虽然也能截取但是前端显示的东西不一样,比如说头部信息。
这里我们要注意,我们是getMapping方法,为什么是这个方法呢?因为我们看到网页上控制台参数,page后面是个问号,问号后面就是他的参数,因此我们只需要截取问号前面的那个单词就可以了,用GetMapping去截取他,括号里面输入他的这个单词,然后去写返回值,返回值应该是什么呢?该怎么写呢?因为我们需要返回一个商品信息,商品结果集也要返回,我们一般返回数据库里面的信息的时候都是用ResponseEntity,这个是专门用来返回数据库的信息的,然后他是一个泛型,你需要加入他的泛型,所以在这里加入了他的返回结果集,然后它返回结果集也是一个泛型,你需要传入商品信息。你可以这么想,我需要返回一个商品信息,返回一个怎么样的商品信息呢?就是要返回一个商品结果集,返回一个怎么样的商品结果集呢?就是要返回我封装好的一个商品信息表。
我们可以回顾一下我们在商品结果集那里泛型传入到哪里,可以看到他传入给一个List,这个List就是商品信息列表,我们传给他之后,他就会显示商品信息。因此商品结果其实不止显示分页跟分页总数,还有商品信息传入泛型就是传入商品信息。
然后回到我们刚刚编写的controller逻辑,我们接下来该写什么呢?我们是不是要编写商品的信息逻辑,那我们的思路应该要怎么走?首先你要去赋值,具体对哪些对象赋值呢?其实我们编写后台业务逻辑的时候,需要看前端的参数进行编写。前端已经给我们写好了。就是哪些地方需要传入哪些参数。比如说他写了一个头,头上有id名字,图片和首字母。这些就需要我们去传入对应的参数。在页面显示中排版都是由前端去完成。我们只需要赋予数据就可以了。所以这就是我们的controller所做的事情,就是赋予数据。因此我们要找到这些数据模型。先看看网页,我们需要去点击,功能组件,然后打开控制台,我们要看看我们需要赋值给哪些参数。
可以看到后面这些参数都是我们需要赋值的。如果你再不明白的话。你可以看看,我们截取了page参数,既然截取了这个参数,我们的目的就是为了修改它后面的参数。也就是问号后面的参数。因此这也是我们接下来要编写的东西。
因此这些参数对应的是什么功能呢?如果前端有给你写注释的话,你就知道他是什么功能,就可以给它赋予相对应的值,如果前端没有给你注释的话,你就要去对应页面查找。
先去找到他的前端赋值,再去查找他对应的方法。
比如说他的方法是一个search。我们就要找到这个search是什么值。
然后这里可以看到它是绑定给我们的搜索框。也就是说,他只是给这个搜索框取了个名字,叫search,然后再给这个search定义一个key,我们需要做就是给这个key赋一个值,也就是赋一个业务逻辑。
在这里设定的是,我们搜索框里面发生变化,结果也会发生变化,这是实时发生变化。
这里顺便说明一下,key是搜索关键字,page和row就是你的分页,sortBy就是根据字段排序,desc就是升序和降序。这些方法都是在前端已经定义好了。也就是说比如分页对应的是哪一个值。已经被定义好。然后取这个名字给你去编写业务逻辑。
所以我们要去截取它的参数,然后用RequestParam方法去获取它的参数,然后括号后面的值我们之前也写过。为什么要这样写呢,不直接写一个双引号,加一个key,因为我们需要设定它的默认值,也就是用户在不输入任何东西的情况下,它显示的是什么,看第一个key,这个是搜索关键字的功能,他是没有默认值的,因为你不知道用户输入什么东西,毕竟搜索关键词这个话,你需要输入东西,它才有东西可以显示,所以他没有默认值,所以我们不用defaultValue去编写,而是直接用request等于false,就是把他请求关闭,让他不显示任何东西,不显示任何东西的话,就是默认前端做的页面。可能有人会说让他显示商品的第一页不好吗?显示商品的第一页是由分页数来决定,而不是由搜索关键字来决定,因此我们把显示第一页的属性加在分页那里。
在这里我们不知道以哪个为标准做升序或者降序。
这里我们还能看到是以id作为降序和升序,但是如果出现了没有显示这些id的情况下,我们该如何知道是降序还是升序?因此我们还是把request等于false。
在我们知道哪些是升序跟降序的时候,我们就可以这样去定义。
那么我们接下来该怎么编写业务逻辑呢?前面说过,我们要获取参数,并且要给这些参数赋值,现在我们赋值好了。还需要做什么呢?
首先你要搞清楚你需要返回结果集,也就是说你缺一个最后返回的对象,看看我们的返回值类型,是ResponseEntity,我们最后返回的结果集肯定是ResponseEntity.ok,如果我们最后返回的是一个数据的话,我们就需要这样去写,所以我们需要一个参数传入OK里面,你可以看看返回值类型,有一个泛型,这也是我们的返回值,所以我们需要去写这个泛型,你就是把我们之前写好了,参数全部传进去:
在编写这个的时候,思路就是我们先要调用service方法,Service方法里面有,这个页面方法,我们要向这个页面方法传入那五个参数,然后它的返回值应该是什么呢?就是我们这个泛型啊。就等于我们相互这个泛型传入五个参数,并且取名为result,然后再把这个result传入到OK里面,就可以了。但是我们要做判断,如果,商品数据为空怎么办?这里的判断有一些技巧,就像我们之前写的一样,如果你先写等于其他这些等于null的话,这样会报错的,这是写判断方法的方法,所以你必须先写null,然后再去写,等于其他方法,这里的判断就是,如果结果等于null,或者结果没有内容,也就是内容为空,那么就执行以下方法,返回状态码,没有找到的状态码404,记住写这些状态码的时候叫加上.build();
无论怎么样,你最终返回的就是一个OK,然后把结果传进去。
我们可以在理清一下思路,首先,我们要从网页控制台获取参数,然后设定ResponseEntit为返回值,然后传入参数那里,需要截取问号后面的参数,然后给他赋值,包括默认值,然后编写方法逻辑,具体这个方法逻辑就是,把这五个参数传入一个service方法,再给他返回ResposeEntity里面的泛型值,这个泛型需要在这里获取五个参数,获取完后做一个业务逻辑判断,如果他不为空,那么就可以返回到OK里面去,也就是把那个泛型传入OK里面去,但如果他为空,那就返回404错误。这就是写分页结果集的controller方法。
接下来我们要写service方法,也就是上图中报红色的那个,因为我们没有写过他的方法,所以他出现了错误。
注意看我们这个service方法,方法名是跟上面的对应了,然后返回值必须要是这个泛型,因为我们在controller里面的方法就是这个泛型,我们令他相等,也就是返回值要和他一样,那五个参数方法照样写进去,方便在controller那里传进来。
然后接下来我们应该编写什么呢?
首先我们要知道我们在controller里面写那个方法有什么作用,还不是为了实现各个参数的功能,这也是我们编写后台的作用,也就是实现前端编写的这些组件功能,因此我们要实现他们的增删改查功能,你可以看到我们这里引入了mapper,那就是因为我们要操作数据库。
我们要实现操作数据库的话,需要编写什么语言?
其实这些你都不用担心,这就是我们mapper方法的意义所在,我们调用这个方法就是因为它能够帮我们去操作数据库,我们只需要想好怎么样去操作就可以了,比如这个key,我们是要实现一个查询的功能,通过关键字来查询,所以我们有两种查询方法,一种是通过id查询,一种是通过首字母进行查询,但是在查询的过程中不是精准查询的,而是使用模糊查询,因此我们需要调用mapper里面的模糊查询方法,还有后面两个page跟rows,这两个是分页的条件,还有后面的升序跟降序,我们等会儿都用mapper方法实现。
我们需要编写这个模糊查询方法,我们要调用map里面的模糊查询方法,只有这个example方法才是模糊查询方法,但是要使用这个example模糊查询方法的话,我们还需要去初始化example对象,因为你要进行模糊查询,所以你要告诉这个example,你要模糊查询的是什么关键字,所以我们需要传入Brand这个实体类,传进去之后id,name等等信息,都可以用来做模糊查询,之后我们还需要创建example实例,完成初始化。
然后我们就需要用这个example实例了,首先我们要做出判断,如果关键词不为空的情况下,我们就可以执行这样的方法:查找一切数据库里面名字有关键词的和查找数据库里面一切首字母有关键词的。那我们应该怎么样去编写这个逻辑呢?
我们可以用ceiteria里面的andlike方法,这个就是一个查找相似方法的方法,它的参数只有两个,一个是你要查找关键词的属性名,另一个就是你要传入关键词,第一个就是我们要查找关键词的属性名是name,然后传入关键词key,你可以留意这一个关键词,他是被两个百分号包住,也就是说在中间如果有关键词的话,就会被查询到,还有一种情况就是首字母也有关键词,所以我们要加上首字母有关键词的方法,也就是letter,然后传入关键词key。完成逻辑。
然后我们再来编写分页条件:
我们只需要用page helper就可以了。调用里面的starPage方法,把两个参数传进去,一个是页数,一个是总页数。这应该就是数据库里面的排序方法,然后传入数据库里面的页数跟总页数。来完成这次在前端页面上的排序。
然后编写我们的排序条件,先判断传进来的id是不是为空,如果不为空的话,我们就可以写排序方法,但是我们应该怎么样去写这个排序方法呢,首先我们先看看mapper里面有无方法,Maple里面没有方法,再去example里面找,因为我们初始化这个对象,所以我们也可以调用它里面的方法,结果在example里面找到一个setOrderByClause方法可以进行升序降序排序,那么具体我们是根据什么来升序降序排序呢?这里我们需要传入参数,首先我们要知道,我们升序降序排序的都是根据id,所以我们需要传入id参数,这里我们的id参数已经被sortBy取代了,所以我们之间用这个sortBy,但是我们需要告诉他是升序还是降序啊,所以后面我们需要用一个三元表达式做判断,三元表达式的写法就在上面红色线部分,问号代表如果是真就执行这个,后面那个表示如果是错的话,就执行后面的,可以看到id后面有个双引号,双引号之间有个空格,那个空格就是留给三元表达式的结果的,只要三元表达式出一个结果,那个结果就进入这个空格里面,完成升序跟降序的排序。
我们要知道这个example,他就是一个例子,我们把东西传进这个例子里面之后,最终还是需要mapper的一个方法去调用它,也就是把这个example例子作为一个参数传进mapper的一个方法里面去,最终返回一个商品列表。
然后我们需要包装它,这个page info是一个组件来的,它是由依赖导入,然后他的功能就是可以把你的商品编写成一个页面,Page info里面有详细的方法,比如说你这个商品该怎么升序降序,还有大概怎么排列?他里面都有方法,所以我们要把之前写好的参数传进来,比如说升序降序的brands,我们已经把example传入brands,这就让商品得到了升序降序的排序,然后我们再用page info去包装它,要注意前面的Brand和后面的brands参数是不一样的,Brands是一个实体类,传入的是属性名,brands是我们刚刚编写好的一个升序降序的排序方法。把他们都传进去是要Page info进行包装,然后最终包装为结果集并返回,最终是怎么包装为结果集的呢?
因为我们事前在pageResult方法里面,写了这个方法,这个方法只有两个参数,一个是页数,一个是商品信息,
我们最终返回的PageResult结果传入了两个参数,两个就是page info里面的方法,一个是分页方法,一个是商品列表方法,这两个方法直接被传入PageResult里面去,并且传入只有两个参数的方法,以这种方式进行了封装。可能有人会问,为什么page results不用传入泛型?因为我们只是完成一个包装的过程,传入一个包装的方法,如果我们传入泛型,将会调用到其他需要传入泛型的方法,比如商品方法,所以在这里我们并不需要传入泛型,只需要传入这两个参数即可,然后完成方法的包装。
然后我们可以做一个优化。这个结果等于空可以去掉了。为什么说可以去掉呢?因为我们刚刚返回new结果集,也就是说无论怎么样都会new一个结果集出来,并且是包装好的结果集,所以结果不可能是空,所以你可以把这个去掉。
最终结果如上。
总结一下,我们这次主要是写关于商品管理后台业务逻辑,我们的思路是怎么样的呢?
首先我们要去封装对象,也就是说要建立一个pojo类,但是要建什么pojo类呢?
像这种前端有参数的话,我们就可以根据前端的各个属性名去建立这个pojo类,这就是我们的思路,也就是无论在什么情况下,你只要看到前端有各个属性名的话,你都可以根据这个各属性名去建立一个pojo类,这是第一步。建立完之后还要去对他们进行get set方法。为什么要建立这个pojo类呢?因为你以后操作这个数据库是需要这个pojo类的,特别是传入关键词后需要搜索的对象,还有升序降序,还有最终包装,都是需要这个类。
除此之外,我们还需要建立一个结果集。这个结果是有什么作用呢?就是你在包装好结果之后,通过这个结果集返回出去,真正显示到页面上的东西,这个就是结果集。
然后网页上控制台上的信息,我们不一定要去建立一个pojo类,但是需要去截取它,并且给它赋值,还有默认值,还要记得去编写他的业务逻辑,我们要返回数据的话一定是ResponseEntity,作为返回值。把最终结果传入OK当中并且传出去,具体怎么包装他,我们需要在service里面调用mapper,然后再用mapper调用example,去编写相对应的业务逻辑,最终用page info进行包装,然后在结果集里面创建只有两个参数的方法,并且把PageInfo包装方法传进去,最终有controller进行传出,整个方法就完成了。