00:00
接下来我们来编写购物车功能,同样的来参照京东页面,我们先来看一下我们这个购物车要做什么,我们来做一个需求分析,首在这个购物车里边,我们先来添加上一个商品,我们来看一下,比如呢,我们现在这儿有一个商品来点进来,我随便呢给购物车里边来添加上一个商品,我在这儿来选中一个商品,我来点一个加入购物车,但是大家现在注意我们这个购物车呢,是加成功了,我们回到首页,但是我呢现在是没有登录状态,我们呢在这看购物车,购物车里边也有相关的信息内容,而且大家注意的是,如果我把这个浏览器关掉,我再来打开京东。我同样的来访问京东,那我们都没有登录购物车里边的内容有没有保存呢?可以看一下,好我们现在访问京东,好,我们发现我的购物车里边,我们之前添加的这个内容还是有,所以呢,首先我们把这块功能我们称为离线购物车,也就是我们的游客购物车,我们在未登录状态下,我们可以有一个购物车,而且只即使浏览器关掉了。
01:08
下次我们再进来购物车里边的数据还有,那接下来我们登录了以后怎么办?那这个登录呢,我先在其他浏览器登一下,我呢不用这个谷歌来登,我先打开火狐,我来登一下我的京东,这样相当于我们用了两个不同的客户端,我先来登录进来,我们先来看一下我们原来我们购物车里边的数据是什么好。我们在这儿来进行扫码登录,我们现在登录成功,来看一下我们原来的购物车,那我们原来购物车里边呢,有116件商品,这是我们登录以后的,好,我现在把这个退出。然后我们现在来看,我们在这个浏览器呢,我没登录,没登录呢,我购物车里边有一个,那如果我在这个浏览器我登录了怎么办?我们现在再来点击登录,我们现在呢,用同一个客户端,我们同时来扫码,我们来登进来,我们以前呢,在火狐里边,我们确认了一下,我们现在有116个商品,但是我现在登录以后来看一下。
02:08
好,我们现在登录成功购物车里边有几个商品呢?我来放上去,诶,我们现在查到了117个商品,为什么会有117个商品相当于呢?把我们刚才没登录状态的购物车的数据也填上边了,我们可以点进来看一下。那我们这个购物车呢,我们当天的这个商品也是有的,没问题的,而且如果我们退出了系统,大家来看,如果我们退出系统,或者我直接将浏览器关掉,我们来再访问京东。京东点com,我们来看一下我们的购物车有多少个商品呢?好,我们来查一下,我们发现呢,现在零件商品,那这是一个什么操作,这就是我们说的非常重要的一个,我们没登录的时候,我们保存的商品相当于一个临时商品,只要我们一登录以后,我们登录了的这个购物车会将没登录的这个购物车里面的数据合并起来,所我们看到了117件商品,而且当我们浏览器关掉,再重新打开,我们呢未登录的这个购物车就被清空了,所以我们会发现时刻呢,在京东里边儿有两个购物车在交互操作,所以接下来我们的重点就放在这两个,一个是我们登录状态,我们的购物车,我们把它称为登录购物车或者在线购物车,或者我们叫用户购物车,这个都行,然后呢,我接下来就是我们没登录状态下的购物车,我们称为游客购物车或者离线购物车,那这两个购物车的交互顺序,我们刚才给大家也大概演示了一下。
03:39
而且呢,我们购物车的特点,好,我们先来说一下这个特点,那再来分析我们这个购物车该存到哪里,首先我们这个登录的这个购物车,它的这个特点呢,就是登录以后,登录以后会将我们这个临时购物车里边的数据,购物车,购物车的数据全部合并过来,全部合并过来,然后呢,临时购物车还会被清空,那这个时购物车就是我们说的这个离线购物车,好我们也可以叫临时购物车,我们来复制过来,会将我们临时购物车数据合并过来,并清空,并清空我们的临时购物车,然后呢,我们如果没登录状态的这个购物车,它的最大特点就是我们浏览器即使关掉,浏览器即使关闭,然后呢,下次下次进入我们这个临时购物车的数据还在,临时购物车数据都在,所以呢,我们现在要保证我们。
04:39
这两个购物车的这两大特点,临时购物车的数据要一直在,除非我们登录以后进行合并,然后我们再来分析一下我们这个购物车,我们如果接下来要写功能的话,我们这个购物车里边呢,肯定就有一些正常的增删改查方法,比如我们来给购物车里边添加一款商品,那就是给购物车里边添加数据,好我们来点进商品的详情页,我们来点一个加入购物车,这是给购物车里边加数据,而且如果我们想要写购物车还应该有什么功能呢?我们鼠标放在这儿,还应该有我们查出所有购物车的数据这些功能。好我们来分析一下我们要写哪些功能,首先我们要写一个查询自己购物车的功能,其次,我们还要给购物车里边能添加商品,好,我们再来加入一个功能,我们要给购物车添加商品,这其实就是购物车的增删改查添加商品,那么还需要什么功能?那购物车里面的商品我们可以去购物车页面看一下,那还能改商品的。
05:39
的数量,所以呢,我们还要做的功能就是修改商品的数量,包括移除删除商品,包括我们选中没选中商品,所以这接下来都是我们将来要做的购物车功能,以及我们这个清理购物车,把整个购物车呢全部清空掉,所以接下来我们要做的功能呢有很多,给购物车添加商品,查询购物车,修改购物车里边的商品数量,包括我们删除购物车里边的一个商品,包括我们选中不选中,诶这个选中不选中,那么这个商品这些呢我们都要做,包括如果做一些复杂的功能,我们刚才也看到,如果我们某一个商品有优惠信息,我们在购物车里边这些展示的时候,那还应该展示这一块呢,有提示商品的优惠信息等等等等,以及京东的购物车还会提示我们,诶,比如购物车里边商品有什么降价,让我们赶紧去购买,所以等等等等,这是我们将来购物车要做的功能,但购物车虽然要做这么多功能,我们在做这个功能。
06:39
提前我们先来分析一下我们购物车要用什么技术,首先我们先来分析一下它存储用什么来存数据,如果是登录状态下,大家注意用户呢,只要一登录了,我们购物车里边的数据是永久存在的,不会清空,所以呢,我们这个会优先选择用MYSQ存储,但是呢,我们再来仔细分析我们这个购物车啊是一个什么操作,们是读多还是写多呢?我们其实发现我们这个购物车是一个读写都是高并发的操作,所以我们购物车里边如果使用数据库,那我们读写都高并发的情况下,我们就要让数据库承担非常大的压力,所以我们可以选择不用数据库,我们根据购物车主这种数据类型,我们都存储的是一条条的,我们称为勾象的这个文档数据,那么可以用一些no s数据库,比如mango DB,它稍微的比我们的数据库能强一点,那但是。
07:39
那我们也不选择用它,原因呢,它的这个性能也并不能带来很大的提升,所以呢,我们可以考虑将我们购物车的数据放到reddi里边,Red呢也是一个no circle,我们这个数据结构内存库,所以我们把它放到red里边的好处是什么?一是我们数据结构好组织,第二个red拥有极高的读写并发性能,但现在呢,如果我们存在red里边,我们会出现一个问题,而大家注意,我们是用户登录以后,我们登录以后的购物车数据我们要持久化保存,大家都知道我们red呢默认是一个内存数据库,那我们所有数据是存在内存的,一旦red宕机,我们这个东西呢,相当于就没有了,但马SQL就不一样,我们只要保存了我们这个数据还在。
08:27
那这种问题呢,我们也不用担心,我们在安装red的时候,我们来可以指定好red的持久化策略,让red每一条数据都能持久化到磁盘里边,即使我们red宕机,下次启动我们数据还有这样呢,虽然能损失一定的性能,相当于我们没有那么高的吞吐量了,但是呢,我们即使这样做也比用my circleq能快很多,所以我们最终呢,选择即使用户登录以后,我们的这个数据存在red里边,那用户没登录,没登录的购物车最大特点它就是一个临时购物车,所以呢,我们也考虑使用red来存储临时购物车的数据呢,我们可以存在很多地方,比如放到local storage local storage呢是其实是浏览器它的一门技术,比如我们所有在零时购物车里面填的数据,我们可以让浏览器自己保存在他自己的local storage,只要是我们的这个客户端用户,他所有。
09:27
的购物车数据都在我们当前浏览器存着,除非浏览器卸载,我们这个数据呢才会丢掉,否则呢数据一直在,但是如果我们存浏览器会有什么问题,相当于我们这个客户端存储,我们数据库不存,我们后台不存客户端存储,如果我们后台不存的话,我们带来的优点就是我们后台的压力很小,但是带来的缺点在我们大数据的时代下,大家会注意每一个人的这个首页啊,他推荐的商品都不一样,比如我这儿秒杀的商品,这是由于我们经常爱给购物车里边放相关的这些,比如电脑啦,积木等等,所以呢他会做一些相关的推荐。所以大数据情况下呢,我们要经常分析某一些人在购物车里边添了哪些数据,即使他没登录,我们也要给他推荐一些这些人爱购买的商品,通过这种大数据分析推荐来提升我们这个购买能力,所以我们这个购物车的数据如果全部都放到我。
10:27
我们的浏览器端,那我们后台呢,就没法分析了,因为我们后台没有存所有人购物车里边都添了什么数据,所以呢,我们一定要将我们后来有价值的数据我们都存到我们后端,那么后端呢,可以选择各种存储技术,那前端我们说的这一些,我们可以将前端让它存到local storage,我们浏览器存或者cookie cookie也是浏览器技术,或者H5引入到web circle,比如我们来可以搜一下,如果大家用H5的话呢,H5也支持我们这个web circleq,相当于我们能在我们这个浏览器的页面,我们也使用它内嵌的这个数据库,但是呢,这些都是我们前端的这些存储方案,而我们说有价值的数据呢,一定都要放到后端,而后端呢,我们这个数据库也好,芒果DB也好,可能基于我们这个性能的一些考虑问题,我们都没有使用,我们最终呢使用了release,所以一句话,我们无论我们用户登录没登录是离线。
11:27
购物车还是在线购物车,是临时的还是永久的,那我们呢,都把所有的数据存到red里边,那既然存到redis里边,那我们就得分析red里边的数据结构应该长什么样子,这样我们才能正确的给red里边存储我们购物车的数据,首先来看我们一个用户呢,肯定对应他一个购物车,答应该是两个购物车,用户没登录,是他的临时购物车,用户登录了,是我们的在线购物车,但是呢,不管是哪个购物车,他们的数据应该是这样的,来点进来看一下,首先这是我们完整的购物车,购物车的所有数据肯定都要存到red里边,购物车的所有数据其实就是我们购买的一件件的商品,我们称为购物项,比如我们再给里边添加一个购物项,好,我们来加入一个购物项,来看一下我们购物车里边的内容,现在呢,我们购物车里边就应该有每一个的购物项,购物项呢有当前购物项。
12:27
是什么商品,它的图片,它的名字,它的价格,我们买了多少件,而且呢,我们买的这个件数,它的这个总计信息,以及如果有优惠的话,还有当前我们这个购物项的优惠信息,我们购物车里边有非常多的购物项,所以如果让我们分析数据结构,我们可能购物车里边应该是这样存储的,我们购物车里边有非常多的购物项,每一个购物项呢,首先都有当前商品的ID,因为我们添加商品,我们是按照SQ添加的,我们看到呢,某一款中意的商品,比如是它这呢,都是当前SQ信息,我点一个加入购物车,给购物车里边加的都是SQ,而且我们从购物车还能跳转到我们当前的这个商,怎么跳转呢?我们肯定就得知道当前商品是什么,所以squ的ID,我们每一个购物项里边呢,肯定有加购物车里边这一个购物项,它呢就拥有SQ的ID,包括呢,我们这一项是被选中还是没选中,这个状态我们也要存储,我们可以给大家看一下。
13:27
我们这个购物车呢,现在是我们这个京东的购物车,我只选中了一项,如果我把浏览器关了,我再来打开京东,京东有没有保存我们哪一项被选中了的这个状态信息来看一下,点进来点击我们购物车,我们发现诶,我们也保存了哪一项是被选中的,所以我们后台呢,还要保存每一个购物项有没有被选中,我们要保存这个,当然还有我们这个购物项的标题,我们要保存商品的标题,商品的默认图片,我们在这儿也要保存,包括我们这个商品的单价,好,我们在这儿呢也要保存,以及商品我们购买的数量,那我们在这儿也要保存,包括我们商品的小G,我们这个总计价格,我们在这儿也要保存,以及我们这个商品的销售属性组和,比如我们是蓝色八加24G,或者怎么着我们在这儿呢,相当于也保存我们销售属性的值,而且呢,大家注意。
14:23
我们这是一个购物项的信息,但是我们这个购物车它应该拥有非常多的购物项,所以购物车呢,应该是这样子的,它是一个数组,数组里边有非常多的购物项,所以我们在red里边,如果我们要保存购物车的内容,那一个购物车呢,就应该是一个数组,数组里边有一个个的购物项,但是我们再来仔细分析,由于red里边呢,保存所有数据都是KV的结构,所以我们这个购物车该在red中如何保存来打开red可以模拟一下,首先我们来分析在red村里边我们保存数据,那们K应该选什么K呢?我们可以这么来写,由于我们是每一个用户,每一个用户都有它对应的啊,应该是两个购物车,它的临时购物车和他登录以后的购物车,所以呢,我们这个K可能应该是这样,我们叫cut,比如我们这个用户的标识,我们用户呢,现在是一号用户,那么就叫cut,一代表一号用户的购物车。
15:24
然后呢,我们这个一号用户的购物车应该是什么类型,我们前面呢分析购物车里边有非常多的购物项,每个购物项呢是一个对象,所以呢,我们购物车应该是一个数组类型,这个数组里边呢放一个一个的对象,所以如果我们来填成我们这个数组类型对象呢,我们保存可以使用杰森,诶这样最简单,比如呢,我们是一号商品,它的标题是什么,我们都可以来保存上,比如我们就叫华为,好,我来点一个保存,这样呢,我们如果使用这种方式来给red里边保存购物车,我们一看CUT1代表一号用户的购物车,那么再来往近一看,它呢是一个数组,数组里边第一个元素是我们这个一号商品,现当于购物车里边的第一项内容,那如果我们的第二项内容,那么又多了一个内容,我们还可以再来添一个,添一个比如我们的二号商品好来点一个,OK,相当于呢,我们每一个用户都有这么一个东西,那如果是二号用户的话,我们来添一个,我们在这呢就叫卡。
16:24
和二,这是二号用户,也是一个list,好来保存两个商品,这是二号用户的购物车,一号用户购物车有两个商品,二号用户购物车呢,也有两个商品,这有一个,那再来添一个,好,我们来添,添上两个,它是三号商品,好,那现在呢,我们这样如果用list来存的话,有没有什么缺点呢?我们来可以看一下,如果在我们这个页面,我们要修改某一个购项,比如呢,我要修改最后一个购物项,这个最后一个购物项呢,我把它的这个数量我改为一,那一旦我改为一,相当于我们red里边的东西也得改,因为我们所有的购物车的购物项数据都在red里边存着,那我们要改,我们就要改什么,我们现在看我们是最后一个购物车的数据,所以我们相当于要把所有的list拿来,我们要找最后一个我来改,但问题现在就是,如果我们填了好多,我们填了100号商品,我们在第93。
17:24
个我们来改了一下,我们怎么知道我们要改哪个商品,购物车里边的哪个商品,可能呢,有两种办法,第一种办法我们先知道我们选的是第几个购物项,比如第93个购物项,因为我们存的是list,我们在list中来找list的时候,找我们list里边第93个元素,但前提是我们这个页面跟我们后台存储的这个呢,顺序还是一模一样的,那我们可能找的是对的,但是呢,我们这样会非常麻烦,所以为了我们后来方便,我们这个找我们的购物项,因为我们经常要修改购物项,它选中了还是不选中了,它的数量我们也经常修改,为了能快速修改,我们可以把购物车里边的这个绿色类型我来去掉,我们变成一个什么类型呢?我们变成一个哈希,好,我把这个flash掉,我们变成这样子的应该比较合理,比如我们来填一个K,那现在呢,CART1代表一号用户的购物车,我让他存成一个哈希,因为哈希呢也是有K,有。
18:24
A的K呢,我们就来写我们当前商品的ID,我们比如是11号商品,V呢,就是我们这个购物项的值,比如SQID,我们的11,然后呢,它的这个价格是多少,比如我们999,我来点一个保存,我们存了一个哈希,那哈希结构呢,看起来就是这样,我们一号用户的购物车第一个数据是11号商品,它的信息是这样,如果我们再来有一个商品,好,我们来第二个我们来存了一个13号商品,它的数据呢是什么样?比我们来SQID13,然后它的价格price,我们叫998,来点一个OK,这样呢,我们就发现我们red里边存每一条数据的时候,由于我们有K,这样的话,假设我们要修改哪个商品了,这是13号商品,所以我们为了方修改red,我们给这个商品的数量我们来加成,三,我们直接可以去red里边找到用户的这个购物车,我们不用挨个便利,看我们是哪个商。
19:24
或者呢,我们按照它的索引去来找,这很麻烦,我们只需要呢,按照我们类似于map的方式,按照K来查询,那么这个K呢,就是商品的ID,我改了哪个商品,我们这个K呢,就有对应商品的详细信息呢,就放在这儿,所以我们red里边存商品不能直接存成一个list list要找商品我们得遍利循环看是哪个商品,但如果我们改为哈希结构,也就是我们说的map,那么以后找商品呢,直接拿商品的ID就能找到,所以最终我们red里边可能存储来的数据是这样子的。这呢,假设是我们的red,每一个黑颜色呢,就是一个购物车,一号用户的购物车,它的件叫CUT1,然后呢,购物车里边存了每一个购物项,购物车整个购物车是一个V纸,这个V呢是一个哈希,相当于我们这个V纸还是有K有V,所以我们最终呢是这样的数据类型结构,好我们呢是一个map,假设我们转成Java,应该是一个map string就是我们的KK呢是我们每一个用户叫CUT1CUT2,每一个用户呢,找到它的这个购物车,这个购物车里边呢,从每一个一个的购物项,所以这个购物车的类型应该是这样,它还是一个map,为了方便找我们这个购物,像这个map的key呢,是一个string,这个string呢就是我们购物项的ID,然后呢。
20:49
Map的值,那就是我们这个购物项的详情,比如我们这个cart item,这个购物项呢,就叫item卡,Item info,所以呢,我们真正的购物车信息应该是这样的,它呢两个K,最前边的这个K,我们这个string呢,我们就来称为K1,这个K1呢就是购物车标识,这是用户标识,标识每一个用户的购物车,所以呢,这个K是跟我们这个用户相关联的标识。
21:21
而我们第二个我们map的这个K,我们就认为这叫K2,这个K2呢,它是跟我们这个购物车购物像的商品ID,这是我们这个购物项的购物车项的商品ID,购物项的商品ID,所以我们最终想要给red边存数据,我们的数据结构在red里边应该是一个哈希,好,我们在red中,在red中我们这个K呢是一个string。它是我们这个用户标识的,而我们这个v value,它呢是一个哈希,哈希结构,哈希结构呢,就是我们说的这个map,而这个哈希的K就是我们商品的ID,它的K是我们这个商品ID,然后呢,它的V是我们当前购物项的详情,购物项详情好,那我们这样呢,就分析了一下购物车的数据结构,那基于这种数据结构,我们下一节课就来编写我们的购物车功能。
我来说两句