00:00
那我们再来回顾一下刚才咱们做的整个的一个流程啊,刚才咱们做的整个的一个流程呢,就是实现了这样的一个文件上传的一个接口,那我们管这个接口呢,其实是通过文件上传的形式,做了一个Excel的批量数据的导入,那现在我们的目标呢,是将Excel当中的数据导入到数据库当中,那目前呢,我们实现了第一个步骤,就是将Excel的数据呢,先上传到了我们的服务器,然后从服务器当中呢,从Excel当中读取数据,把数据呢读到内存当中,那整个的流程呢,我们再来看一下,就是首先是前端这面调用一个后端的啊iport的接口,那后端的port的接口呢,就在我们的这个地方啊进行了一个实现,然后接下来呢,我们从file这个里面拿到input stream传递给我们的service,在我们的service这块,我们呢,执行了一个监听器对象的一个创建,啊,那通过这个监听器对象的创建呢,我们去。
01:01
进行Excel的读对吧,然后最后呢,去执行这个真正的读,那我们希望呢,从监听器从这个input stream里面读出的数据呢,自动的通过监听器封装到我们的Excel d to这个类型的对象里面,那么具体的封装的过程呢,是在监听器的内部实现的,我们不需要去实现封装的过程,我们只需要去把。监听器,人家这里面给咱们封装好的数据拿出来就行了,所以已经封装好了,给底层封装了,然后呢,咱们在这就拿出来,拿出来之后咱们就要在这个地方调用map层的save方法啊,进行一个数据的一个存储了,好那接下来呢,我们来说一下。这个map层的这个save方法,咱们具体呢来怎么去实现,那首先呢,我们先来思考一个问题哈,啊,那因为我们在读Excel的时候呢,它将会有很多行,比如说50行,100行,1万行啊,10万行都有可能,对不对?好,当我们的数据量比较小的时候,比如说50行记录,那是不是意味着这个地方会有什么呀?
02:11
会执行50次啊,那这个地方执行50次的话,你在这个地方调用这个map层的税方法,是不是会执行50次的数据库访问呀,那这个实际上效率就不是特别高了啊,那如果我们的Excel表当中有100万条记录,那么我们在这个地方读的时候,是不是要执行100万次log方法啊,从而会执行100万次数据库的插入操作呀,那这样的话效率就太低了,是不是?所以我们呢,要在这个地方做一个优化,优化什么呢?就是我们希望呢啊,有一个批量保存的这么一个方法啊,所以呢,我们在这个地方来实现一个批量保存,我们怎么样去实现批量保存呢?比如说。我们呢,在这个地方解析到数据的时候,我们先别着忙把它存起来,我们先把这个数据呢存到一个列表里啊,然后列表达到一定数量的时候,比如说列表当中我们积累了100条记录的时候,咱们在一次性的把100条记录呢存到数据库里,这样的话,大家想如果我有1000条数据,那我在这个地方每100条记录存一次,是不是1000条数据,虽然这边执行了1000次解析,但是最后我们只向数据库中插入十次色口就行了,因为我们做的是批量存储,对吧?这样的话呢,就极大的提高了我们数据插入的效率啊,那所以呢,我们先把贝塔。
03:39
每一次解析出来的时候呢,存到一个数据列表里,那所以在这个地方呢,我们就创建一个数据列表啊,这个数据列表呢,我们就它的数据类型呢,就是Excel这个d to了。这样不行哈,那这样写。
04:05
List啊,Excel d to,然后呢,我们创建一个数据列表,等于这个new list,好,那这块呢,就是我们的数据。列表就数据列表好,然后接下来呢,我们呃,在这个位置,每次读取出来一个数据的时候呢,我们先别着忙存,我们先把这个数据呢艾到这个数据列表里。叫做贝塔好将数据存入数据列表。啊,然后接下来呢,我们设置一个值,什么值呢?就是你不能一直存,你一直存的话,比如说100万条记录,它一直把这100万条记录全都存到数据列表里,然后我们用一条语句把100万条记录一次性的插入到数据库中,这个数据库它也不支持,因为数据库那边接口那边它一次不能接收过大的一个色Q语句的长度,如果你这个色Q语句太长了,数据库那面它它处理不了,明白吧,所以呢,一般情况下呢,根据我们的这个实际经验啊,我们这面呢,就是生产环境下,一般一次性的处理3000条左右的记录啊,当数据数据的列数不太多的时候,这个你还是要根据实际的数据的每一行的数据数,数据列啊的这个大小,数据的这个列当中的这个数据的长度,你要去这个灵活的去调整,那一般情况下呢,就是生产环境下,我们一次性的在列表里面放入3000条记录,然后一次性的用一条批量插入的S语句。
05:48
把这3000条记录插入到数据库当中,这个是常见的一个临界值的一个范围,那么在测试的过程当中,我们实际上这里面没有那么多记录,对吧,我们就这几十条,所以呢,我们就呃设计一个测试的一个一个临界值啊,比如说我们给这个临界值呢,设计为五,就每有五条记录我们存一次,然后真正到生产环境的时候,我们把这个五呢再改成3000,好吧,所以呢,这块是static,我们设置一个常量值final。
06:19
嗯,我行吧。我们设计这样的一个值啊,然后这个数据列表看看啊,先暂时用定义好,然后接下来呢,这个呢就是。每隔五调剂。路存储一次数据是吧,啊批量吧,批量存储一次数据,好,那么也就意味着这面我们是不是得判断这个list的长度啊,每当list大于等于五的时候,我们呢,就存数据,然后呢,把list似清空,再重新往里插,然后类似又大于等于五了,我们再存数据,然后把类似清空,再重新往里插啊好,那所以呢,这个地方我们就写if。
07:13
list.s的值,当它大于等于这个Bach count的时候,那我们呢,再做一个数据保存啊,然后呢,这个数据保存呢,一会我们写到一个辅助方法里啊,比如说save data,好,然后呢,我在下面这个地方呢,我先写一个save data方法,这个是一个辅助方法哈。对对,辅助方法我们就写private吧,Private啊,Wide save data,好,每一次存的时候我们都调用它,所以这块呢,我们打印一个日志吧,落点in啊啊。占位符啊,几条数据被存储到数据库,然后这单位符里面写什么呢?写list.size我们每五条预存,每五条预存啊具体怎么存呢?我们这个地方呢,调用map层的思路方法明白吧啊,存完了之后呢,我们再打印一个日志,叫做数据存储完毕,几条数据存储到数据库成功行吧啊。
08:35
就是正式存着呢啊,然后这个是成功,然后这中间就存,所以这块呢,一会儿我们要写一个调用map层的save方法啊,这样的一个过程,然后呢,而且呢,我们调用map层的save方法呢,我们要save谁呀,要save这个list list当达到五的时候,我们就把这个list批量存啊。这类对象明白吧,好,然后接下来呢,我们来看一下这面啊,当save完这个data之后,我们呢,再把这个list.clear再给它清空掉啊,清空完列表的时候,下一次再来到这个引log方法当中,那么我们重新解析的记录是不是又重新追加呀?好,一条,两条,三条,四条,五条,好五条又到五条了,是不是又存一遍,存一遍又清空,然后又到五条又存,直到把所有的记录都存完为止,好,如果我们的记录有50条,那么这个方法是不是执行50次?好,50条记录是都存进去了,好,如果我们的记录有52条。
09:41
那你想,如果我们的记录有52条的话,第50条存完了之后,第51条是不是加到这个类型里面,第52条是不是加到这个类子里面,好后面还会有第53条记录吗?不会有了,所以呢,第53次的引log方法不会被执行,那么如果第53次不会被执行类,此时此刻它的长度就是二,对吧?因为五十一五十二嘛,类似长度不可能大于五了,不可能大于五,这个C5方法就调用不到,这个C5方法调用不到最后那两条记录,五十一五十二这两条记录。
10:20
那就没法存怎么办?收尾的地方存啊,Do after all last,我们把最后不足五条记录的数据呢,在这个地方进行存储啊,所以save data明白吧啊,所以收尾的时候还要再调一下啊,然后就不足当最后剩余的数据,嗯,数据记录数。不足。这个的时候,那我们。呃,最终一次性。
11:04
存储剩余数据是吧,是这个意思啊好,所以这块呢,整个就是这个业务逻辑了,那么现在的问题。就只有一个了,就是把map对象传递进来,好map对象怎么传呢?有的同学可能就想到了,之前在service里面传map,就是写一个resources,然后啊,我们的Di map这个麦粉,这样是错的。为什么?因为如果你这个map可以自动的注入到用这个resources啊,自动的注入到这个对象当中的话,那么前提是你这个对象必须是被spring管理的,就意味着我们这个对象必须至少要有一个类似于component这样的注解,它是被spring容器自动管理的,你才能再注入进来,只有他被管理了,才继续来管理他的依赖,对不对?Spring连他爸都没管理你,你儿子更别想了,是吧?所以说既然我们现在这个Excel。
12:16
Detail listener啊,它没有被spring管理,那我们的这listener也不能通过自动注入的方式进行注入,那我们怎么样去注入呢?我们通过可以通过构造函数来注入,那么如何通过构造函数来注入呢?我们在这里面呢,可以去创建一个构造函数啊,按out加insert。好,我们呢执行这个constructor,我们呢执行这个。就是第一个吧,选第一个啊啊OK,好,我们呢,通过这个Di map来生成一个什么呀,来生一个Excel Di listen对象,然后接下来呢,我们再给它去写一个无参的构导函数啊,因为啊,一般情况下有了有参构导函数之外呢,我们都通常情况下会给它加一个无参的哈,叫做no ask construct,这个是无参构造函数,然后这个是那个有一个参数的构造函数,好这样的话呢,我们来看它编译后的结果啊,这个就是通过注解写的那个无参构造函数,这个呢,就是刚才我们写的有参的构函数,好那么我们通过这个构造函数把这个map可以注入进来啊,所以这个构造函数在哪调用的呀,是不是在刚才咱们的service层调用的。
13:36
啊,这是调用的嘛,在这个service里面我们可以注入。所以呢,在service里面,咱们其实呢,注入的map呢,就是那个。Base就是resource嘛,Resource,然后private private private resource private啊,然后date map date map正常情况下应该是他吧,是不是T,然后date map是不是,然后那我们之前说过,如果啊,你当前注入的这个map就是当前这个service下的map的话,是不是不用写了,直接写base map就可以吧,就在这构造函数这块,我们直接写base map就行了啊,然后我们把这base map呢,通过这个构造函数啊,传递到我们当前的这个listener这个里面来,然后那我们现在这个listener里面呢,它就有map了。
14:35
啊,有了map之后呢,我们就可以。我们就可以去在当前的这个位置。这个位置啊,去调用map层的save方法,我们调用的方法呢,是批量保存啊。批量保存方法,好,然后接下来呢,我们在这边写啊,Di map点我们写一个方法insert,当然这方法还没有呢,你不得我们自己实现Bach in色t Bach叫批量保存,把谁批量保存进去呢?List,明白这意思吧,啊,所以这是我们的批量保存方法,然后啊,整个的这个流程呢,就是每一次去invoke的时候,先把数据放到类里面,然后类似数量达到我们的临界值,我们就批量保存一次,然后清空list。
15:32
啊,然后在。注入list,再添追加list类数量又达到临界值,我们再批量保存,每一次批量保存调用的就是这个颜色的BA方法哈,最后剩余不足这个BA count的这个数量的数据的时候,我们再在do after这个里面再保存一次,然后保存的时候又调用这个方法,所有的数据就保存到数据库当中了啊,所以这块是我们整个的一个业务逻辑了,那最后一个步骤就是我们把音色的BA给它实现出来。
我来说两句