Java秒殺系統(tǒng)(三):整體業(yè)務(wù)流程介紹與數(shù)據(jù)庫設(shè)計(jì)
作者:
修羅debug
版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 by-sa 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。
摘要:本篇博文是“Java秒殺系統(tǒng)實(shí)戰(zhàn)系列文章”的第三篇,本篇博文將主要介紹秒殺系統(tǒng)的整體業(yè)務(wù)流程,并根據(jù)相應(yīng)的業(yè)務(wù)流程進(jìn)行數(shù)據(jù)庫設(shè)計(jì),最終采用Mybatis逆向工程生成相應(yīng)的實(shí)體類Entity、操作Sql的接口Mapper以及寫動(dòng)態(tài)Sql的配置文件Mapper.xml。
內(nèi)容:對(duì)于該秒殺系統(tǒng)的整體業(yè)務(wù)流程,相信機(jī)靈的小伙伴在看完第二篇博文的時(shí)候,就已經(jīng)知道個(gè)大概了!因?yàn)樵谔峁┑脑创a數(shù)據(jù)庫下載的鏈接中,Debug已經(jīng)跟各位小伙伴介紹了該秒殺系統(tǒng)整體的業(yè)務(wù)流程,而且還以視頻形式給各位小伙伴進(jìn)行了展示!該源碼數(shù)據(jù)庫的下載鏈接如下:https://gitee.com/steadyjack/SpringBoot-SecondKill 在本篇博文中Debug將繼續(xù)花一點(diǎn)篇幅介紹介紹!
一圖以概之,如下圖所示為該秒殺系統(tǒng)整體的業(yè)務(wù)流程:
從該業(yè)務(wù)流程圖中,可以看出,后端接口在接收前端的秒殺請(qǐng)求時(shí),其核心處理邏輯為:
(1)首先判斷當(dāng)前用戶是否已經(jīng)搶購過該商品了,如果否,則代表用戶沒有搶購過該商品,可以進(jìn)入下一步的處理邏輯
(2)判斷該商品可搶的剩余數(shù)量,即庫存是否充足(即是否大于0),如果是,則進(jìn)入下一步的處理邏輯
(3)扣減庫存,并更新數(shù)據(jù)庫的中對(duì)應(yīng)搶購記錄的庫存(一般是減一操作),判斷更新庫存的數(shù)據(jù)庫操作是否成功了,如果是,則創(chuàng)建用戶秒殺成功的訂單,并異步發(fā)送短信或者郵件通知信息通知用戶
(4)以上的操作邏輯如果有任何一步是不滿足條件的,則直接結(jié)束整個(gè)秒殺的流程,即秒殺失敗!
如下圖所示為后端處理“秒殺請(qǐng)求”時(shí)的核心處理邏輯:
綜合這兩個(gè)業(yè)務(wù)流程,下面進(jìn)入“秒殺系統(tǒng)”的數(shù)據(jù)庫設(shè)計(jì)環(huán)節(jié),其中,主要包含以下幾個(gè)表:商品信息表item、待秒殺信息表item_kill、秒殺成功記錄表item_kill_success以及用戶信息表user;當(dāng)然,在實(shí)際的大型網(wǎng)站中,其所包含的數(shù)據(jù)庫表遠(yuǎn)遠(yuǎn)不止于此!本系統(tǒng)暫且濃縮出其中核心的幾張表!如下圖所示為該“秒殺系統(tǒng)”的數(shù)據(jù)庫設(shè)計(jì)模型:
緊接著,是采用Mybatis的逆向工程生成這幾個(gè)數(shù)據(jù)庫表對(duì)應(yīng)的實(shí)體類Entity、操作Sql的接口Mapper以及寫動(dòng)態(tài)Sql的配置文件Mapper.xml。如下圖所示:
下面,貼出其中一個(gè)實(shí)體類以及相對(duì)應(yīng)的Mapper接口和Mapper.xml代碼,其他的,各位小伙伴可以點(diǎn)擊鏈接:https://gitee.com/steadyjack/SpringBoot-SecondKill 前往下載查看!首先是實(shí)體類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;
//采用服務(wù)器時(shí)間控制是否可以進(jìn)行搶購
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配置文件的源代碼:
<!--查詢待秒殺的活動(dòng)商品列表-->
<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>
<!--搶購商品,剩余數(shù)量減一-->
<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>
<!--搶購商品,剩余數(shù)量減一-->
<update id="updateKillItemV2">
UPDATE item_kill
SET total = total - 1
WHERE id = #{killId} AND total>0
</update>
</mapper>
值得注意的是,上面實(shí)體類ItemKill、ItemKillMapper接口的相應(yīng)方法及其對(duì)應(yīng)的動(dòng)態(tài)Sql的含義,各位小伙伴可以暫且忽略,在后面介紹到相應(yīng)的業(yè)務(wù)實(shí)戰(zhàn)時(shí)將會(huì)再次進(jìn)行重點(diǎn)介紹。
至此,關(guān)于“秒殺系統(tǒng)”整體的業(yè)務(wù)流程、后端接口的核心處理邏輯以及Mybatis逆向工程的應(yīng)用等就介紹到這里了。下一節(jié)將進(jìn)入實(shí)際的代碼實(shí)戰(zhàn)環(huán)節(jié)!
補(bǔ)充:
1、目前,這一秒殺系統(tǒng)的整體構(gòu)建與代碼實(shí)戰(zhàn)已經(jīng)全部完成了,該秒殺系統(tǒng)對(duì)應(yīng)的視頻教程的鏈接地址為:https://www.fightjava.com/web/index/course/detail/6,可以點(diǎn)擊鏈接進(jìn)行試看以及學(xué)習(xí),實(shí)戰(zhàn)期間有任何問題都可以留言或者與Debug聯(lián)系、交流!
2、另外,Debug也開源了該秒殺系統(tǒng)對(duì)應(yīng)的完整的源代碼以及數(shù)據(jù)庫,其地址可以來這里下載:https://gitee.com/steadyjack/SpringBoot-SecondKill 記得Fork跟Star?。。。?/span>
3、最后,不要忘記了關(guān)注一下Debug的技術(shù)微信公眾號(hào):