1. 程式人生 > >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、由於相應的部落格的更新可能並不會很快,故而如果有想要快速入門以及實戰整套系統的,可以參考: Java商城秒殺系統的設計與實戰視訊教程(SpringBoot版)


2、目前,這一秒殺系統的整體構建與程式碼實戰已經全部完成了,完整的原始碼資料庫地址可以來這裡下載:https://gitee.com/steadyjack/SpringBoot-SecondKill 記得Fork跟Star啊!