00:00
接下来我们再来编写远程查询库存的功能。首先我们在这设置每一个SQ的时候,我们还要给它保存上它。当前SQ是否有库存,叫set handsto,如果有就是true,否则呢就是false。但是库存的检索功能我们是要在库存服务里边进行的。而且呢,如果我们每次便利在这儿调用一个远程的库存查询,那我们会调用八次的远程调用,那这样呢是一个很慢的过程,所以呢,我们期望远程服务呢,有一个接口可以统一帮我们来查到这些所有SQ到底有没有库存。我们在这呢,只需要设置好当前SQ是否有库存就行了。那我们就可以先给远程接口,我们先来编写一个功能,我们来到它的controller里边,我们库存的这个controller里边,好,我们先来编写第一个远程,咱们这个是查询库存,查询SKU是否。有库存,而且呢,我们只查询是否有,并不需要查询多少个等等,那么可以来写一个功能,比如public r,我来写一个get sqsto,我们就叫汉字to,我们是否是拥有库存,而我们这个方法的签名呢,我们将所有想要查询的SKU的ID,我们批量呢传过来,我们就来写一个浪浪呢,我们就将SKU ids。
01:28
而且呢,这是用接森方式传过来的,那我就来写request body,将请求题里面的接森数据给我转换成这个集合,好,那么接下来我们要处理的请求,那么就来要写一个post卖品,因为请求题里边要放数据,只有post请求,请求题里边才能放数据。那我们这块的功能就叫handsto,我们就叫hands字to,来看它是不是拥有库存,然后希望呢,就有一个v SQ service这个方法,他呢能帮我们来查出我们这些SQ对应的商品是否拥有库存。
02:05
那这一块返回什么呢?我们其实返回最基本的信息就行了,虽然说数据库里边我们设计的,我们来看一下,我们打开WMS,我们在这里边我们设计的是SQ的ID,对应的库存有多少个,以及等等其他的仓库信息,SQ的名字,包括锁定了多少库存,那实际上呢,我们只需要知道当前SQ有没有库存,那我们呢,就返回一个基本的,比如当前SQ的ID。以及他当前的库存量是多少。只要大于零,那就是有库存,因为从数据库里面查出库存量也是很快的,因为我们要众多的查询,所以我们肯定要返回一个list。那这个list呢,我们封装最简单一个VO,只有我们的SQID和我们的这个库存量,比如我们来放在这儿,我们就叫s ku看子to VO。
03:03
那这一块呢,我们来给它先来加上an data方法。然后我们来写上我们的两个属性,第一个是我们浪类型的SKUID和它到底有没有库存。我们来写一个布尔类型的汉字to,好,我们希望呢,最终来返回我们这个数据,我们叫SQ汉字to VO,我们就将VS把这个数据返回,最终呢,统一返回出去来return。啊,点OK,来put一个,我们所有的数据呢,我们都放在data里边,这是我们的VS。好,我们把它拿过来。那么希望就有这么一个方法,我们来创建出来这个方法呢,帮我们来检查每一个商品的库存啊,我们来创建出这个方法。那我们因为要逐一检查,所以我们需要来做一个遍历SQ ids,点一个stream来进行一个映射map,每一个SQ我们来都来检查,最终检查呢,返回一个这个对象,那么先来写上它VO,就等于new,一个SKU,汉字to VO,那么接下来就要在这来进行检查,检查呢肯定要查数据库。
04:20
最终把检查到的这个VO,我们来返回封装,把它呢封装成一个集合,第二,Collect to list。然后我们把它最终来返回,这就是我们要检索的数据。那接下来我们在这儿就要做一个功能,就是查询当前SKU的总库存量。那怎么查呢?我们就需要用到我们库存的这个service,我们叫where SQ的service,那就是它当前的这个service,我们调用他的这个base member,这个best member呢,就是v SQ do,那它最终呢,就会查询我们的这个VSQ表。
05:04
而我们如何检索库存,我们需要来发送这样一个SQL语句,好,我们来测试一下。首先我们每一个SQ可能呢,不止在某一个仓库有那么多个仓库呢,都有库存,所以呢,我们库存其实是求它的总库存。那么先来写上最简单的SQL语句,来写一个select,先from我们的这张表,Where,我们的SQID是我们指定的值,来写上SQID等于,比如我们来看一号的,但是呢,我们现在只来看库存,那如果我只来写一个stock走,那现在呢,他查到的是一号的库存,它有两个数,但我们要记总数,我们写一个sum函数来给它算一个总量,那算一个总量我们现在来走,那它呢就有111个库存,但实际上呢,总库存又不是这个样子,我们是库存里边的这个数量需要减去他锁定的这些库存,锁定的库存那就是别人下单已经占用了,但是还没支付完,这个逻辑呢,我们后来会说,但是我们这一块呢,得给他减去。
06:11
比如我们这一块模拟一下,这一块的锁定库存是十个,这一块的锁定库存是一个,那么现在呢,总共锁定的库存相当于呢有11个,那他的总库存就应该是100个,因为他之前总库存是111个,那这个S库怎么写呢?我们就需要在求总和的时候,把它的这个库存量我们来给它也减一下,我们来测试一下。走,那现在呢,我们就看到库存总量是100个,这我们查询一个SQ对应的总库存的内容,好我们把它复制过来,那么现在要查库存,相当于就来发送这个SQ语句,那假设呢,我们就来有一个方法就叫get SKU stock获取我们某一个SKU所有的库存总量,我们传入我们当前SQ的ID来写一个SQ,第2GET来我们不用get ID,因为我们传的这个SQ就是ID的集合,那我们将SQ这个就放在这,我们就叫SQID吧,好,SQID,那我们现在呢,把SQID传进来。
07:16
那最终呢,会给我们返回一个计数,我们浪类型的一个count,那按照这个计数我们就会判断它是否有库存,我们先来set上。我们要返回的这个数据里边SQID,那就是当前的,还有它是否有库存will.set handsto。那就是我们的count大于零,那如果大于零,那就是有库存了,我们的这个do还没有这个方法,那我们就先来创建出这个方法,那创出这个方法呢,我们就顺便来添加上它的实现好来。给它生成statement,在我们马be斯的map文件里边,好把这个方法呢,生成了以后,我们接下来把我们的SQL语句拿过来,我们的circleql语句呢,就是这条语句,我们把它复制过来,CTRLC复制到这。
08:05
那这一块的SQID我们就写上井号大括号,我们传入的SQID,这在我们方法的签名上呢,哎,有我们这个值,如果签名上只有一个参数,我们写什么都行,多个参数一定要用an p标注每一个参数的属性名,我们最终用什么好,那我们的这个检查库存方法就好了,那最终呢,我们调用这个方法查到了所有的库存,然后呢,我们返回出了这个集合,那我们远程的这个功能,那我们就返回了。那接下来我们就要查库存,那我们就需要调用远程这些功能,先把右边的这些关掉,我们留下好,现在我们来调用远程的检索库存功能,那调用远程服务们首先的这个商品服务,我们就要导入份,我们这一块呢,已经导入了份open份,我们也开启了远程调用,那接下来呢,就来写一个远程调用接口,我们来到我们的分包下,里边呢,都是我们以前所有的远程调用接口,那再来写一个接口,那么这个接口呢,就是where,所有跟库存系统交互的远程接口,Well,份service,好。
09:15
首先呢,在接口上我们得来标注,第一个注解叫分client,它是一个分客户端,这个客户端它调用哪个远程服务的功能,那么就在这儿标注一下,我们是调用我们库存服务的功能,然后呢,接下来我们要调用的第一个方法,那来到我们库存服务里边,相当于是我们的检索库存,好把它直接复制过来,只要方法签名一样,那就没什么问题,走大家注意这一块的整个完整路径,我们把它一定要复制过来,我就叫VRVRSQ啊,复制过来好杠加上。这时我们来进行库存的检查,我们就不用写public,那来到po info service里边来注入这个远程服务,我们就叫where库存服务的我们这个份客户端。
10:02
份service,好,我们就叫where份service,来按auto where来进行远程调用,来到我们这,我们远程调用来查询是否有库存,而且我们这个查询呢,我们是批量返回的,所以呢,我在外边直接一次性查完,把这一块呢,我就拿过来,我们先来调这个份service,第二它有一个方法get我们的所有库存,那么在这呢是统一查到,统一查到以后呢,接下来在下边挨个匹配它是否有库存。那么现在就要拿到所有我们要查到SQ的ID集合,那所有的SQ的ID呢,我们先来聚合一下,我们在SQS里边点一个stream点。慢。那最快的方式我们可以这么来简写,SQ info entity,那么调用这个实体类里边的获取sqidd方法。把它得到的这个值,我们最终呢,给它集合起来,我们点一个collect to list。
11:04
好,我们把这个呢拿到这是我们SQID。Li我们的整个集合,那我们接下来就要查询这些SKU对应的所有的库存信息,我们把它传过来,那最终呢,会返回一个R对象,那这个R对象呢,这是远程服务给我们返回的主要这个R对象里边它有一个data data塔呢是这个list类型的VO。那我们要做的就是呢,我们在这远程调用成功以后,我们还得从R里边获取到它data的内容,然后呢,把data内容再转换为我们的那个类型。其实大家发现这样做呢,就复杂多了,所以其实我们这些提供给我们远程进行调用的这个功能,为了解决我们返回值这一块的问题,我们可以有两种方案,第一种方案我们就是R,在当时设计的时候,我们设计的时候可以加上泛型,可以加上咱们这个泛型。
12:04
比如我们点进R。R里边呢,还有一个属性,它有一个private类型的,它是泛型的data数据,那我们点R这呢,我们来给它加上泛型,那这样做的好处是什么呢?那我们返回的整个R数据,我们在这呢,就可以来写上泛型,哎,我们说我们返回的就是那个list类型的什么什么什么。Spring mvc就会自动帮我们进行逆转,但是呢,由于我们现在R已经没有加上这些泛型了,我们来写上它的get set方法,比如我们用al insert,我们来插入我们这个data的get set方法,包括我们来写上它的set data。我们在这设计的时候呢,没有泛型,那其他人想要用这些泛型,我们来看,那我们这个R,由于全系统共用,一开始没设计上泛型,那其他的时候想要用泛型,然后可能呢,每一个接口为了精确期间我们都需要在这儿来改一遍。
13:04
那大家呢,可以来后来去来修改这个,所以这是我们说的第一个我们加上泛型,第二个我们直接可以让他返回list类型的这个数据,诶我们就直接返回我们想要的结果,这样呢,我们也不用操心这些转换数据了。那我们ctrler这一块,我们就需要写上我们不返回R了,我们就返回这个类型的数据,我们把这呢复制过来,比如我们把这复制过来放到这儿,我们返回。这是我们第二种做法,那第三种,那么就需要自己封装咱们这个解析结果,比如我们还是返回为R,但R里边的data数据是各种类型的,那我们还想要很方进变的逆转过来使用,那么可以给R里边专门来提供一个方法,它可以将我们的这个数据转换成什么样的类型。
14:04
那好,我们现在呢,就使用泛型设计的啊,因为我们返回的有各种结果。那接下来我们的这一块的controller,我们就先来改掉。我们返回到整个R里边,我们真正的数据是这个类型的,好我们来加上,然后我们r.OK的时候,好r.OKr.OK呢,它会返回一个R对象,把这个R对象呢先拿来走。我们给R里边放数据呢,就可以不用put放一个data了,那么就可以用这我们直接给OK里边set我们data内容呢,就是我们这个VS,最终我们将这个OK进行返回。那么在这呢,也可以直接给他限定上泛型类型。来限定上这个返型类型,那这就是我们的这种返回,那这种返回的好处是什么?别人在这儿远程调用的时候,那么这一块呢,远程调用的这个R,我们直接将它的ctrler方法,我们签名拿过来,好,我们就将这一块呢,直接签名拿过来,我们来到我们的这个service里边走。
15:13
那这样呢,我们得到的整个R里边本身它里边的data,我们只要获取过来,那就是这个类型的对象。也不用我们自己再来写那些把Jason再转过来再转过去的功能了,因为spring boot底层就给我们已经进行逆转了,当我们这个VO呢,由于我们只在V这个系统里边我们写了一遍,所以呢,我们想要逆转过来,我们还给得给我们的商品系统里边再写一个VO,那我就可以把这个VO复制过来,我们给这里边再放一份,只要他们的这个属性名是一样,哪怕他们的这个VO。但这个类名不一样,这都无所谓,因为最终都是JS转成我们这个对象的,所以我们说最快的方式呢,我们就可以给common里边放过去,我把它呢就称为to,反正都是要进行数据传输的啊,我们放进去。
16:06
那这个呢,我给这儿也放一份给common里边走放过来。那接下来我们在这远程调用的时候,我们要封装的数据,我们就导致于common就行了,那我们远程调用结束了以后,我们来到这儿,我们整个的这一块返回来,我们重新写一下,它调用完我们就会返回这个类型的数据,那这个类型的数据我们想要用它的真正内容,我们只需要调用get data,那么就可以把它里边的之前查到的所有内容我们就拿到了,所以这就是我们泛型化设计的好处。我们这个泛型在small boot底层在进行AB2个服务传输期间,它也会给我们自动转化过来,好,那接下来我们这个就写好了,我们查询远程的库存,那接下来在这一块它到底有没有库存,那么就得知道,那怎么知道呢?我们可以用一个这样的方式,我们来快速的得到它的库存,我们将它的这个data,由于它是一个list,那stream点一个,我们可以把这个list转成一个map,如果map里边是我们squ的ID,我们在下边呢,就可以很快的得到当前SQID对应到底有没有库存,所以呢,我们可以用这个方法点collect,我们给它收集,但收集成一个什么呢?我们使用collectors,我们把它收集成一个map,点一个,我们有一个方法叫to map,那图map里边呢,让我们提供两个函数,一个就是把什么当成K的运算函数,一个呢是把它什么当成map里面的值,那当成。
17:40
K呢?那其实就是我们这个里边正在遍历的,那这个VO里边的ID我们是当成K的,所以我来写一个冒号,它里边的SQID我们当成K,而什么当成值?我们当前遍历的这个对象,我们可以直接把当前的这个对象返回,我们把这个对象变成值,我们也可以直接让它返回对象里边的汉字to,这个值直接返回出false。那么这个简写方式呢,跟我们以前加上小括号,这写个大括号return是一样的,因为我们说如果只有一句话要return,我们就可以省略大括号,省略return,好我们写了一种这样的方式,好我们来得到我们最终的这个结果,那这个map里边的结果呢,那就是按照SQ的ID和它到底有没有东西组合成了一个map,那接下来我们这一块到底有没有库存,那就超级快了,我们只需要通过库存的这个map,比如叫sto map里边,好,我们从它里边。
18:40
获取到当前SKUID对应是否有库存就行了,我们拿到当前SKU的ID。第2GETSQID。那这样呢,我们就可以拿到是否有库存,而且呢,大家一定要注意,由于我们这一块呢,是一个远程调用,远程调用呢有可能网络波动,服务不稳定等各种原因,可能会产生失败,一旦一失败,这一块抛异常以后,那我们下边呢可能都不走了,所以我们在这儿可以给它串一下,如果远程调用失败了,好,远程调用失败了,那么也让它继续保存,但继续呢,我们都默认是有库存的,好,Catch来写一个exception e,好,如果有问题,我们可以先来日志记录一下log error,我们叫库存服务查询,出现问题我们就将异常查询异常,然后呢,我们将异常的原因,我们这儿有一个原因。
19:41
我们将原因呢写一个占位符,我们将整个异常对象打印到这儿,所以我们最好的做法是将这两句话我们放到串块里边,好,CTRLX们直接剪过来,那如果有的话,那我们的这个map就不是空的,我们可以给它。
20:00
默认先整一个空,那如果没有的话,那map那就有就为空了,我们如果远程查询出现异常,这个map就为空了,所以呢,我们就在这儿判断,如果这个map是空的。那我们默认就给它是有数据好来判断if。我们的to map。等等,那那如果远程服务有问题了,即使有问题我们也给他,让他有数据,那我们就让他写一个处,否则了才按照map里边我们检索到的库存信息来,那么就来写一个ES model.set汉字to,我们从这个map里边拿过来,我们get,按照当前的SQ id.get ID我们拿过来,当我们stream这一块呢,要求它外边用到这个东西是一个翻的,我们这儿相当于经过了两次扶持。把这呢处理一下,我们将这个直接复制过来,利用它的这个提示,我们前面附好值,我们在这呢复制过来,我们判断这个这个的值一直是不变的,好,那我们这一步就做完了,我们来设置库存信息,我们在这儿设置库存信息,那下一节课呢,我们就将整个数据发给ES进行保存。
我来说两句