zoukankan      html  css  js  c++  java
  • Java秒杀系统实战系列~整体业务流程介绍与数据库设计

    摘要:

    本篇博文是“Java秒杀系统实战系列文章”的第三篇,本篇博文将主要介绍秒杀系统的整体业务流程,并根据相应的业务流程进行数据库设计,最终采用Mybatis逆向工程生成相应的实体类Entity、操作Sql的接口Mapper以及写动态Sql的配置文件Mapper.xml。

    内容:

    对于该秒杀系统的整体业务流程,相信机灵的小伙伴在看完第二篇博文的时候,就已经知道个大概了!因为在提供的源码数据库下载的链接中,Debug已经跟各位小伙伴介绍了该秒杀系统整体的业务流程,而且还以视频形式给各位小伙伴进行了展示!该源码数据库的下载链接如下:https://gitee.com/steadyjack/SpringBoot-SecondKill  在本篇博文中Debug将继续花一点篇幅介绍介绍!

    一图以概之,如下图所示为该秒杀系统整体的业务流程:

    从该业务流程图中,可以看出,后端接口在接收前端的秒杀请求时,其核心处理逻辑为:

    (1)首先判断当前用户是否已经抢购过该商品了,如果否,则代表用户没有抢购过该商品,可以进入下一步的处理逻辑

    (2)判断该商品可抢的剩余数量,即库存是否充足(即是否大于0),如果是,则进入下一步的处理逻辑

    (3)扣减库存,并更新数据库的中对应抢购记录的库存(一般是减一操作),判断更新库存的数据库操作是否成功了,如果是,则创建用户秒杀成功的订单,并异步发送短信或者邮件通知信息通知用户

    (4)以上的操作逻辑如果有任何一步是不满足条件的,则直接结束整个秒杀的流程,即秒杀失败!

    如下图所示为后端处理“秒杀请求”时的核心处理逻辑:

     

    综合这两个业务流程,下面进入“秒杀系统”的数据库设计环节,其中,主要包含以下几个表:商品信息表item、待秒杀信息表item_kill、秒杀成功记录表item_kill_success以及用户信息表user;当然,在实际的大型网站中,其所包含的数据库表远远不止于此!本系统暂且浓缩出其中核心的几张表!

    如下图所示为该“秒杀系统”的数据库设计模型:

    紧接着,是采用Mybatis的逆向工程生成这几个数据库表对应的实体类Entity、操作Sql的接口Mapper以及写动态Sql的配置文件Mapper.xml。如下图所示:

    下面,贴出其中一个实体类以及相对应的Mapper接口和Mapper.xml代码,其他的,各位小伙伴可以点击链接:https://gitee.com/steadyjack/SpringBoot-SecondKill 前往下载查看!首先是实体类ItemKill的源代码:

    import com.fasterxml.jackson.annotation.JsonFormat;
    import lombok.Data;
    import java.util.Date;
    @Data
    public class ItemKill {
        private Integer id;
        private Integer itemId;
        private Integer total;
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
        private Date startTime;
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
        private Date endTime;
        private Byte isActive;
        @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
        private Date createTime;
        private String itemName;
        //采用服务器时间控制是否可以进行抢购
        private Integer canKill;
    }

    然后是ItemKillMapper接口的源代码:

    import com.debug.kill.model.entity.ItemKill;
    import org.apache.ibatis.annotations.Param;
    import java.util.List;
    public interface ItemKillMapper {
        List<ItemKill> selectAll();
        ItemKill selectById(@Param("id") Integer id);
        int updateKillItem(@Param("killId") Integer killId);
        ItemKill selectByIdV2(@Param("id") Integer id);
        int updateKillItemV2(@Param("killId") Integer killId);
    }

    最后是ItemKillMapper.xml配置文件的源代码:

    <!--查询待秒杀的活动商品列表-->
      <select id="selectAll" resultType="com.debug.kill.model.entity.ItemKill">
        SELECT
          a.*,
          b.name AS itemName,
          (
            CASE WHEN (now() BETWEEN a.start_time AND a.end_time AND a.total > 0)
              THEN 1
            ELSE 0
            END
          )      AS canKill
        FROM item_kill AS a LEFT JOIN item AS b ON b.id = a.item_id
        WHERE a.is_active = 1
      </select>
      <!--获取秒杀详情-->
      <select id="selectById" resultType="com.debug.kill.model.entity.ItemKill">
        SELECT
          a.*,
          b.name AS itemName,
          (
            CASE WHEN (now() BETWEEN a.start_time AND a.end_time AND a.total > 0)
              THEN 1
            ELSE 0
            END
          )      AS canKill
        FROM item_kill AS a LEFT JOIN item AS b ON b.id = a.item_id
        WHERE a.is_active = 1 AND a.id= #{id}
      </select>
    
      <!--抢购商品,剩余数量减一-->
      <update id="updateKillItem">
        UPDATE item_kill
        SET total = total - 1
        WHERE
            id = #{killId}
      </update>
    
      <!--获取秒杀详情V2-->
      <select id="selectByIdV2" resultType="com.debug.kill.model.entity.ItemKill">
        SELECT
          a.*,
          b.name AS itemName,
          (CASE WHEN (now() BETWEEN a.start_time AND a.end_time)
            THEN 1
           ELSE 0
           END)  AS canKill
        FROM item_kill AS a LEFT JOIN item AS b ON b.id = a.item_id
        WHERE a.is_active = 1 AND a.id =#{id} AND a.total>0
      </select>
    
      <!--抢购商品,剩余数量减一-->
      <update id="updateKillItemV2">
        UPDATE item_kill
        SET total = total - 1
        WHERE id = #{killId} AND total>0
      </update>
    </mapper>

    值得注意的是,上面实体类ItemKill、ItemKillMapper接口的相应方法及其对应的动态Sql的含义,各位小伙伴可以暂且忽略,在后面介绍到相应的业务实战时将会再次进行重点介绍。

    至此,关于“秒杀系统”整体的业务流程、后端接口的核心处理逻辑以及Mybatis逆向工程的应用等就介绍到这里了。下一节将进入实际的代码实战环节!

    补充:

    1、目前,这一秒杀系统的整体构建与代码实战已经全部完成了,完整的源代码数据库地址可以来这里下载:https://gitee.com/steadyjack/SpringBoot-SecondKill 记得Fork跟Star啊!!!

    2、实战期间有任何问题都可以留言或者与Debug联系、交流;QQ技术交流群:605610429,顺便关注一下Debug的技术微信公众号呗:

  • 相关阅读:
    Django和Angular.js模板标签冲突的解决方式
    ImageMagick 使用经验
    Getting Real内容浓缩
    RA layer request failed
    [硬件结构]硬件体系结构中的缓存的定性与定量分析案例
    hdu5373
    百度地图之标注一组地理坐标&lt;2&gt;
    【KMP】hdu1867(A + B for you again) 杭电java a题真坑
    hdu1034 简单模拟
    杂谈之WEB前端project师身价
  • 原文地址:https://www.cnblogs.com/SteadyJack/p/11193418.html
Copyright © 2011-2022 走看看