redis构建web应用(二)

一、前言

在《redis构建web应用(一)》中,我们实现了三个基本功能:
(1) 记录登录用户的token和用户名
(2) 记录每个用户最近浏览的五个商品
(3) 当登录网站的用户量超服务器限制时,使用淘汰最近最久未使用算法删除一部分用户所对应的信息
通过上篇blog的练习,读者是否对redis的数据类型应用有了更加强的印象了呢,在本文中,我们将继续完善web应用的一些基础功能。如果对Java语言不熟悉,也可以自行选择任意一种能够连接redis的语言进行完成,如果对其他语言也不熟悉,那还是跟着我一起用Java吧,文章结尾有学习讨论群和Java系列文章。

二、本文主要功能

本文的主要功能是:
(1)实现用户的购物车功能
(2)实现推荐用户购买功能

三、相关功能实现

3.1 实现用户的购物车功能

如果是真实的web项目前后端联动开发,那可能更方便理解,因为图形化界面更加符合人类对事物的认知,但是因为我们现在的学习是专注后端,在本文的例子中不掺入前端,所以实现购物车的逻辑得先捋清楚。
每位用户的购物车采用散列(HASH)的数据结构进行存储
在这里插入图片描述
使用过有淘宝的小朋友肯定知道,添加购物车商品的数量是使用图像界面的,从购物车删除商品也是使用图形界面的,因此小伙伴们没有看见过数量为负数的商品被添加到购物车。而在本文所构建的web应用中,如果用户订购的某件商品,并输入数量,则添加进购物车,如果此前购物车就有这件商品,将两次的订购数量相加,如果数量大于零,则覆盖此前已有的订购数量,如果数量小于等于零,则程序会在购物车散列中自动移除该商品。以下是程序的逻辑图。
在这里插入图片描述

具体实现代码如下:

/**
     * 添加购物车
     * 入参:Jedis连接,商品名,添加购物车数量
     */
    public static void addShoppingCart(Jedis conn, User user, String goodsName, int count) {
        /**
         * 先判断购物车中是否有这个商品*/
        int a = 0;//默认购物车中没有,则数量为0
        if (conn.hget("cart:" + user.getToken(), goodsName) != null) {
            a = Integer.valueOf(conn.hget("cart:" + user.getToken(), goodsName));
        }
        System.out.println("a = " + a);
        /**
         * 购物车中已有这个商品
         * 再将两者数量相加,最终订购数量小于0,则移除*/
        if ((count + a) <= 0) {
            conn.hdel("cart:" + user.getToken(), goodsName);
            System.out.println("购物车中商品数量为负,已被自动删除");
        } else {
            conn.hset("cart:" + user.getToken(), goodsName, String.valueOf(count + a));
            System.out.println("添加购物车成功," + goodsName + "在购物车中的数量是" + conn.hget("cart:" + user.getToken(), goodsName));
        }
    }

运行程序测试一下:
在这里插入图片描述
也许你会觉得,好像上面的代码块没写这些中文输出的语句,为什么我运行程序会出现这些东西,实际上,这些非主要功能的代码是在main()函数里面给用户以提示的,代码的全貌可以去文末链接下载源码,仔细查看。如果所有的代码都贴到博客里面来,那用处也不大的,编程最重要的还是思维逻辑。
那么,我们来看一下我们的redis里面是否已经存储了我们的商品。
先查看kelvin的token
在这里插入图片描述
根据token再来查看购物车
在这里插入图片描述
符合我们的预期逻辑。

3.2 实现商品推荐

商品推荐可以分为个性化商品推荐和大众化商品推荐,其中个性化实现起来较为复杂,涉及一些复杂的算法,在这里就不做展示,读者可自行研究实现。那么接下来我们的主要的关注地方就在于大众推荐。
大众推荐比较类似于给商品进行积分排序,被浏览被购买的时间越接近分数就越高,浏览次数和购买次数越多,分数就越高。
因为要排序,所以我们需要一个ZSET来存储商品名和商品排序分
在这里插入图片描述
对于排序分值的算法,我们规定是,
a、越新排名越高,因此分值里面要加入时间戳,这里的时间戳应指商家上架的时间戳而不是用户自己购买的时间戳,那么在本次应用中,我们默认所有商品上架的时间戳都一样,所以就不加入了,但是实际项目中是不一样的哦。
b、浏览量越高排名越高,因此分值要加入浏览量X10(浏览分值常数)
c、购买数量越多排名越高,因此分值要加入购买数量X50(购买分值常数)
(因为我们的应用没有加入支付模块,所以我们视加入购物车为购买)
还有比较重要的一点,因为我们要求的是分数越高排名越靠前,但是ZSET中排序是按照分值从小到大排序的,也就是说我们想要排在前面的商品被ZSET排在了后面,故而工程师们想了一个有趣的办法,就是使用负数将所有的分值都置为负数,那么分数绝对值越高的商品就可以排的越靠前了。
那么我们就可以回到购物车的代码块中,在添加购物车的语句后面加上一个为商品加分的语句了。

conn.zincrby("goods:",-count*50,goodsName);//添加购物车加分

再回到浏览商品的地方添加浏览商品的分值

conn.zincrby("goods:",-10,goodsName);//浏览一次加10分

对代码稍作整理(对照文末源码查看)之后运行程序
在这里插入图片描述
细心的读者可以计算一下各个商品的分值,反正我是不想算的,毕竟我对我的程序充满信心。
在这里插入图片描述
好了各位,redis构建web应用到此就告一段落了,后续会继续深入实战演练的。

总结

一个完整的web应用肯定不止这一点点功能,但是在一个web中的相关功能的实现方式就是如上两篇文章所写的这样。如果大家想完善这个web应用,那么请继续认真学习吧,并且还需要较好的前端能力。处于redis的入门级别,我们做到这里已经非常不错了。
本文源码下载地址:
http://47.99.164.123:8088/root/redisLearn.git

对Java系列知识感兴趣的朋友可以加入QQ群
慧梦软件开发技术联盟:952317701
更多系列文章在java高级程序开发微信公众号
Java高级开发技术

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值