VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > Java教程 >
  • 第八章 分布缓存实战-List-Hash数据结构最佳案例实战

第1集 在线教育-天热销视频榜单实战-List数据结构设计

简介:在线教育-天热销视频榜单实战-List数据结构设计

  • 需求

    • 小滴课堂官网需要一个视频学习榜单,每天更新一次
    • 需要支持人工运营替换榜单位置
  • 企业中流程

    • 定时任务计算昨天最多人学习的视频
    • 晚上12点到1点更新到榜单上
    • 预留一个接口,支持人工运营
  • 类似场景

    • 京东:热销手机榜单、电脑榜单等
    • 百度:搜索热榜
  • 疑惑:为啥不是实时计算,真正高并发下项目,都是预先计算好结果,然后直接返回数据,且存储结构最简单

image-20210411192134001

 

 

 

 

 

 

 

 

 

 

第2集 在线教育-天热销视频榜单实战-编码最佳实践

简介:在线教育-天热销视频榜单实战-编码最佳实践

  • 开发接口
 
 
 
 
 
 
    @RequestMapping("rank")
    public JsonData videoRank(){
        List<VideoDO> list = redisTemplate.opsForList().range(RANK_KEY,0,-1);
        return JsonData.buildSuccess(list);
    }
 
  • 测试数据
 
 
 
 
 
 
@Test
  void saveRank(){
        String RANK_KEY = "rank:video";
        VideoDO video1 = new VideoDO(3,"PaaS工业级微服务大课","xdclass.net",1099);
        VideoDO video2 = new VideoDO(5,"AlibabaCloud全家桶实战","xdclass.net",59);
        VideoDO video3 = new VideoDO(53,"SpringBoot2.X+Vue3综合实战","xdclass.net",49);
        VideoDO video4 = new VideoDO(15,"玩转23种设计模式+最近实战","xdclass.net",49);
        VideoDO video5 = new VideoDO(45,"Nginx网关+LVS+KeepAlive","xdclass.net",89);
        redisTemplate.opsForList().leftPushAll(RANK_KEY,video4,video5,video3,video2,video1);
    }
 
  • 人工运营操作榜单
 
 
 
 
 
 
    /**
     * 替换榜单第二名
     */
    @Test
    void replaceRank(){
        String RANK_KEY = "rank:video";
        VideoDO video = new VideoDO(42,"小滴课堂面试专题第一季高级工程师","xdclass.net",89);
        //在集合的指定位置插入元素,如果指定位置已有元素,则覆盖,没有则新增
        redisTemplate.opsForList().set(RANK_KEY,1,video);
    }
 

 

 

 

 

 

 

第3集 自营电商平台-购物车实现案例-Hash数据结构最佳实践

简介:自营电商平台-购物车实现案例-Hash数据结构最佳实践

  • 背景

    • 电商购物车实现,支持买多件商品,每个商品可以买不同数量
    • 支持高性能处理

image-20210218224622798

  • 购物车常见实现方式

    • 实现方式一:存储到数据库

      • 性能存在瓶颈
    • 实现方式二:前端本地存储-localstorage-sessionstorage

      • localstorage在浏览器中存储 key/value 对,没有过期时间。
      • sessionstorage在浏览器中存储 key/value 对,在关闭会话窗口后将会删除这些数据。
    • 实现方式三:后端存储到缓存如redis

      • 可以开启AOF持久化防止重启丢失(推荐)

     

  • 购物车数据结构介绍

    • 一个购物车里面,存在多个购物项

    • 所以 购物车结构是一个双层Map:

      • Map<String,Map<String,String>>
      • 第一层Map,Key是用户id
      • 第二层Map,Key是购物车中商品id,值是购物车数据
  • 对应redis里面的存储

    • redis里面有多种数据结构,应该使用哪种?
    • 答案是 hash结构

    image-20210221210955210

 

 

 

 

 

 

 

 

第4集 高并发下的互联网电商购物车实战-相关VO类和数据准备

简介:高并发下的互联网电商购物车实战-相关VO类和数据准备

  • VideoDO类
  • CartItemVO
 
 
 
 
 
 
public class CartItemVO {
    /**
     * 商品id
     */
    private Integer productId;
    /**
     * 购买数量
     */
    private Integer buyNum;
    /**
     * 商品标题
     */
    private String productTitle;
    /**
     * 图片
     */
    private String productImg;
    /**
     * 商品单价
     */
    private int price ;
    /**
     * 总价格,单价+数量
     */
    private int totalPrice;
    public int getProductId() {
        return productId;
    }
    public void setProductId(int productId) {
        this.productId = productId;
    }
    public Integer getBuyNum() {
        return buyNum;
    }
    public void setBuyNum(Integer buyNum) {
        this.buyNum = buyNum;
    }
    public String getProductTitle() {
        return productTitle;
    }
    public void setProductTitle(String productTitle) {
        this.productTitle = productTitle;
    }
    public String getProductImg() {
        return productImg;
    }
    public void setProductImg(String productImg) {
        this.productImg = productImg;
    }
    /**
     * 商品单价 * 购买数量
     * @return
     */
    public int getTotalPrice() {
        return this.price*this.buyNum;
    }
    public int getPrice() {
        return price;
    }
    public void setPrice(int price) {
        this.price = price;
    }
    public void setTotalPrice(int totalPrice) {
        this.totalPrice = totalPrice;
    }
}
 

 

  • CartIVO
 
 
 
 
 
 
public class CartVO {
    /**
     * 购物项
     */
    private List<CartItemVO> cartItems;
    /**
     * 购物车总价格
     */
    private Integer totalAmount;
    /**
     * 总价格
     * @return
     */
    public int getTotalAmount() {
        return cartItems.stream().mapToInt(CartItemVO::getTotalPrice).sum();
    }
    public List<CartItemVO> getCartItems() {
        return cartItems;
    }
    public void setCartItems(List<CartItemVO> cartItems) {
        this.cartItems = cartItems;
    }
}
 

 

  • 数据源层
 
 
 
 
 
 
@Repository
public class VideoDao {
    private static Map<Integer,VideoDO> map = new HashMap<>();
    static {
        map.put(1,new VideoDO(1,"工业级PaaS云平台+SpringCloudAlibaba 综合项目实战(完结)","https://xdclass.net",1099));
        map.put(2,new VideoDO(2,"玩转新版高性能RabbitMQ容器化分布式集群实战","https://xdclass.net",79));
        map.put(3,new VideoDO(3,"新版后端提效神器MybatisPlus+SwaggerUI3.X+Lombok","https://xdclass.net",49));
        map.put(4,new VideoDO(4,"玩转Nginx分布式架构实战教程 零基础到高级","https://xdclass.net",49));
        map.put(5,new VideoDO(5,"ssm新版SpringBoot2.3/spring5/mybatis3","https://xdclass.net",49));
        map.put(6,new VideoDO(6,"新一代微服务全家桶AlibabaCloud+SpringCloud实战","https://xdclass.net",59));
    }
    /**
     * 模拟从数据库找
     * @param videoId
     * @return
     */
    public VideoDO findDetailById(int videoId) {
        return map.get(videoId);
    }
}
 
  • json工具类
 
 
 
 
 
 
public class JsonUtil {
    // 定义jackson对象
    private static final ObjectMapper MAPPER = new ObjectMapper();
    /**
     * 将对象转换成json字符串。
     
     * @return
     */
    public static String objectToJson(Object data) {
        try {
            String string = MAPPER.writeValueAsString(data);
            return string;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 将json结果集转化为对象
     *
     * @param jsonData json数据
     * @param clazz 对象中的object类型
     * @return
     */
    public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
        try {
            T t = MAPPER.readValue(jsonData, beanType);
            return t;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
 

 

 

 

 

 

 

 

 

第5集 高并发下的互联网电商购物车实战-加入购物车接口开发

简介:电商购物车实现案例-加入购物车接口开发

  • 添加购物车接口
 
 
 
 
 
 
    @RequestMapping("addCart")
    public JsonData addCart(int videoId,int buyNum){
        //获取购物车
        BoundHashOperations<String, Object, Object> myCart = getMyCartOps();
        Object cacheObj = myCart.get(videoId+"");
        String result = "";
        if (cacheObj != null) {
            result = (String) cacheObj;
        }
        if (cacheObj == null) {
            //不存在则新建一个购物项
            CartItemVO cartItem = new CartItemVO();
            //从数据库查询详情,我们这边直接随机写个
            VideoDO videoDO = videoDao.findDetailById(videoId);
            videoDO.setId(videoId);
            cartItem.setPrice(videoDO.getPrice());
            cartItem.setBuyNum(buyNum);
            cartItem.setProductId(videoId);
            cartItem.setProductImg(videoDO.getImg());
            cartItem.setProductTitle(videoDO.getTitle());
            myCart.put(videoId+"", JsonUtil.objectToJson(cartItem));
        } else {
            //存在则新增数量
            CartItemVO cartItem = JsonUtil.jsonToPojo(result, CartItemVO.class);
            cartItem.setBuyNum(cartItem.getBuyNum() + buyNum);
            myCart.put(videoId+"", JsonUtil.objectToJson(cartItem));
        }
        return JsonData.buildSuccess();
    }
 
  • 购物车方法抽取
 
 
 
 
 
 
   /**
     * 抽取我的购物车通用方法
     *
     * @return
     */
    private BoundHashOperations<String, Object, Object> getMyCartOps() {
        String cartKey = getCartKey();
        return redisTemplate.boundHashOps(cartKey);
    }
    /**
     * 获取购物车的key
     *
     * @return
     */
    private String getCartKey() {
        //从拦截器获取 ,这里写死即可,每个用户不一样
        int userId = 88;
        String cartKey = String.format("product:cart:%s", userId);
        return cartKey;
    }
 

 

 

 

 

 

 

 

 

第6集 高并发下的互联网电商购物车实战-查看和清空购物车功能开发

简介:高并发下的互联网电商购物车实战-查看和清空购物车功能开发

  • 查看我的购物车
 
 
 
 
 
 
 @GetMapping("/mycart")
    public JsonData findMyCart(){
        BoundHashOperations<String,Object,Object> myCart = getMyCartOps();
        List<Object> itemList = myCart.values();
        List<CartItemVO> cartItemVOList = new ArrayList<>();
        for(Object item: itemList){
            CartItemVO cartItemVO = JsonUtil.jsonToPojo((String)item,CartItemVO.class);
            cartItemVOList.add(cartItemVO);
        }
        //封装成cartvo
        CartVO cartVO = new CartVO();
        cartVO.setCartItems(cartItemVOList);
        return JsonData.buildSuccess(cartVO);
    }
 
  • 清空购物车
 
 
 
 
 
 
 @GetMapping("/clear")
public JsonData clear() {
        String cartKey = getCartKey();
        redisTemplate.delete(cartKey);
         return JsonData.buildSuccess();
}
 

 

 

 



来源:https://www.cnblogs.com/Xd17324217006/p/14921697.html


相关教程