01 整合IDEA+Maven+SSM框架的高並發的商品秒殺項目之業務分析與DAO層
作者:nnngu
項目源代碼:https://github.com/nnngu/nguSeckill
這是一個整合IDEA+Maven+SSM框架的高並發的商品秒殺項目。我們將分為以下幾篇文章來進行詳細的講解:
- 01 Java高並發秒殺項目之業務分析與DAO層
- 02 Java高並發秒殺項目之Service層
- 03 Java高並發秒殺項目之web層
- 04 Java高並發秒殺項目之高並發優化
項目的效果圖
秒殺商品列表
開始秒殺提示界面
秒殺結束提示界面
新建一個Maven項目
以IntelliJ IDEA為例,點擊File > New > Project > Maven
然後點擊Next繼續;
填寫相關信息,點擊Next;
最後點擊Finish,完成創建。
如果右下角彈出下面這個提示,點擊Enable Auto-Import
創建webapp目錄
點擊File > Project Structure
步驟1
步驟2
步驟3
步驟4
步驟5
步驟6
步驟7
步驟8
構建pom文件
Maven項目創建好了,接下來我們要添加一些jar包的依賴,也就是在pom.xml
中添加各種開源組件的坐標。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.nnngu</groupId>
<artifactId>nguSeckill</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 代碼省略,請參照項目的源代碼 -->
... ...
完整的代碼,請查看項目裏的pom.xml
文件
到此,我們項目的初始化工作完成。
秒殺系統業務分析
秒殺系統業務流程如下:
由圖可以發現,整個系統其實是針對庫存做的系統。用戶成功秒殺商品,對於我們系統的操作就是:
減庫存
記錄用戶的購買明細。下面看看我們用戶對庫存的業務分析:
記錄用戶的秒殺成功信息,我們需要記錄:1、誰購買成功了。2、購買成功的時間/有效期。3、付款/發貨信息。這些數據組成了用戶的秒殺成功信息,也就是用戶的購買行為。
為什麽我們的系統需要事務?看如下這些故障:1、若是用戶成功秒殺商品我們記錄了其購買明細卻沒有減庫存。導致商品的超賣。2、減了庫存卻沒有記錄用戶的購買明細。導致商品的少賣。對於上述兩個故障,若是沒有事務的支持,損失最大的無疑是我們的用戶和商家。在MySQL中,它內置的事務機制,可以準確的幫我們完成減庫存和記錄用戶購買明細的過程。
MySQL實現秒殺的難點分析:當用戶A秒殺id為10的商品時,此時MySQL需要進行的操作是:1、開啟事務。2、更新商品的庫存信息。3、添加用戶的購買明細,包括用戶秒殺的商品id以及唯一標識用戶身份的信息如電話號碼等。4、提交事務。若此時有另一個用戶B也在秒殺這件id為10的商品,他就需要等待,等待到用戶A成功秒殺到這件商品然後MySQL成功的提交了事務他才能拿到這個id為10的商品的鎖從而進行秒殺,而同一時間是不可能只有用戶B在等待,肯定是有很多很多的用戶都在等待拿到這個行級鎖。秒殺的難點就在這裏,如何高效的處理這些競爭?如何高效的完成事務?在後面第4個模塊如何進行高並發的優化為大家講解。
我們這個系統需要完成秒殺的哪些功能?先來看看天貓的一個秒殺庫存系統:
大家看了是不是覺得很復雜?當然不用擔心,我們只是實現秒殺的一些功能:1、秒殺接口的暴露。2、執行秒殺的操作。3、相關查詢,比如說列表查詢,詳情頁查詢。我們實現這三個功能即可。接下來進行具體的編碼工作,首先是建立數據庫以及Dao層的編碼。
建立數據庫
-- 創建一個數據庫
CREATE DATABASE ngu_seckill;
-- 使用數據庫
USE ngu_seckill;
-- 省略...
... ...
完整的數據庫sql代碼,在項目的sql
文件夾裏的ngu_seckill.sql
創建實體類
先創建秒殺商品類com/nnngu/entity/Seckill.java
package com.nnngu.entity;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 秒殺商品
*/
public class Seckill implements Serializable {
private static final long serialVersionUID = 2912164127598660137L;
/* 主鍵ID*/
private long seckillId;
/* 秒殺商品名字 */
private String name;
/* 代碼省略,請參照項目的源代碼 */
... ...
創建秒殺狀態類com/nnngu/entity/SuccessKilled.java
package com.nnngu.entity;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 秒殺後的狀態
*/
public class SuccessKilled implements Serializable {
private static final long serialVersionUID = 1834437127882846202L;
private long seckillId;
/* 用戶的手機號碼*/
private long userPhone;
/* 代碼省略,請參照項目的源代碼 */
... ...
為實體類創建對應的mapper接口,也就是dao接口
com/nnngu/dao/SeckillMapper.java
package com.nnngu.dao;
import com.nnngu.entity.Seckill;
import org.apache.ibatis.annotations.Param;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
public interface SeckillMapper {
/* 代碼省略,請參照項目的源代碼 */
... ...
}
com/nnngu/dao/SuccessKilledMapper.java
package com.nnngu.dao;
import com.nnngu.entity.SuccessKilled;
import org.apache.ibatis.annotations.Param;
public interface SuccessKilledMapper {
/* 代碼省略,請參照項目的源代碼 */
... ...
}
創建對應的mapper.xml
在resources
目錄下創建com.nnngu.dao
包,然後創建SeckillMapper.xml
和 SuccessKilledMapper.xml
,如下圖:
com.nnngu.dao/SeckillMapper.xml
<!-- 這裏的代碼省略 -->
<!-- 請參照項目的源代碼 -->
com.nnngu.dao/SuccessKilledMapper.xml
<!-- 這裏的代碼省略 -->
<!-- 請參照項目的源代碼 -->
創建Mybatis的配置文件mybatis-config.xml
mybatis-config.xml
配置文件的內容參照項目的源代碼
建立連接數據庫的配置文件jdbc.properties
註意: jdbc.properties
裏面的屬性要根據自己的情況進行修改。
建立Spring的dao的配置文件
創建applicationContext-dao.xml
如下圖:
applicationContext-dao.xml
文件的具體代碼請參照項目的源代碼。
測試
創建測試類 com/nnngu/dao/SeckillMapperTest.java
如下圖:
該文件的具體代碼請參照項目的源代碼。
測試結果
測試查詢所有商品的方法queryAll()
測試結果如下:
到此,我們成功完成了Dao層開發及測試。下篇文章 02 Java高並發秒殺項目之Service層
01 整合IDEA+Maven+SSM框架的高並發的商品秒殺項目之業務分析與DAO層