1. 程式人生 > >二、高併發秒殺API之Dao層設計實現

二、高併發秒殺API之Dao層設計實現

一、Idea建立maven

1、File——-》new———》project
這裡寫圖片描述

2、選擇maven
這裡寫圖片描述

點選next!

3、輸出專案名,包(表示web專案,以後可以spingMVC連起來用)

這裡寫圖片描述
點選next!

4、如下圖 maven倉庫可以選擇你自己的

這裡寫圖片描述

下一步!

這裡寫圖片描述

點選完成!

5、在main檔案下新建Java檔案 放原始碼
這裡寫圖片描述

(1)web.xml檔案改變servlet版本,相關問題見

(2)pom.xml檔案引入依賴

二、資料庫設計和實現

資料庫構建主要是兩個表的建立:秒殺表、明細表

CREATE TABLE seckill(  
  `seckill_id`
BIGINT NOT NUll AUTO_INCREMENT COMMENT '商品庫存ID', `name` VARCHAR(120) NOT NULL COMMENT '商品名稱', `number` int NOT NULL COMMENT '庫存數量', `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間', `start_time` TIMESTAMP NOT NULL COMMENT '秒殺開始時間', `end_time` TIMESTAMP NOT
NULL COMMENT '秒殺結束時間', PRIMARY KEY (seckill_id), key idx_start_time(start_time), key idx_end_time(end_time), key idx_create_time(create_time) )ENGINE=INNODB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8 COMMENT='秒殺庫存表';
-- 初始化資料 INSERT into seckill(name,number,start_time,end_time) VALUES
('1000元秒殺iphone6',100,'2016-01-01 00:00:00','2016-01-02 00:00:00'), ('800元秒殺ipad',200,'2016-01-01 00:00:00','2016-01-02 00:00:00'), ('6600元秒殺mac book pro',300,'2016-01-01 00:00:00','2016-01-02 00:00:00'), ('7000元秒殺iMac',400,'2016-01-01 00:00:00','2016-01-02 00:00:00');
-- 秒殺成功明細表 -- 使用者登入認證相關資訊(簡化為手機號) CREATE TABLE success_killed( `seckill_id` BIGINT NOT NULL COMMENT '秒殺商品ID', `user_phone` BIGINT NOT NULL COMMENT '使用者手機號', `state` TINYINT NOT NULL DEFAULT -1 COMMENT '狀態標識:-1:無效 0:成功 1:已付款 2:已發貨', `create_time` TIMESTAMP NOT NULL COMMENT '建立時間', PRIMARY KEY(seckill_id,user_phone),/*聯合主鍵*/ KEY idx_create_time(create_time) )ENGINE=INNODB DEFAULT CHARSET=utf8 COMMENT='秒殺成功明細表';

三、Dao層設計開發

結構:
這裡寫圖片描述

1、Entity
建立實體類Seckill.java

package entity;

import java.util.Date;

/**
 * @Author:peishunwu
 * @Description:
 * @Date:Created  2018/6/1
 */
public class Seckill {
    /**
     * 商品庫存ID
     */
    private long seckillId;
    /**
     * 商品名稱
     */
    private String name;
    /**
     * 庫存數量
     */
    private int number;
    /**
     * 秒殺開始時間
     */
    private Date startTime;
    /**
     * 秒殺結束時間
     */
    private Date endTime;
    /**
     * 建立時間
     */
    private Date createTime;

    public long getSeckillId() {
        return seckillId;
    }

    public void setSeckillId(long seckillId) {
        this.seckillId = seckillId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public Date getStartTime() {
        return startTime;
    }

    public void setStartTime(Date startTime) {
        this.startTime = startTime;
    }

    public Date getEndTime() {
        return endTime;
    }

    public void setEndTime(Date endTime) {
        this.endTime = endTime;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }
}

建立SuccessKilled.java

package entity;

import java.util.Date;

/**
 * @Author:peishunwu
 * @Description:
 * @Date:Created  2018/6/1
 */
public class SuccessKilled {
    /**
     * 商品庫存ID
     */
    private long seckillId;
    /**
     * 使用者手機號
     */
    private long userPhone;
    /**
     * 狀態標識:-1:無效 0:成功 1:已付款 2:已發貨
     */
    private short state;
    /**
     * 建立時間
     */
    private Date createTime;
    /**
     * 秒殺庫存表實體
     */
    private Seckill seckill;

    public long getSeckillId() {
        return seckillId;
    }

    public void setSeckillId(long seckillId) {
        this.seckillId = seckillId;
    }

    public long getUserPhone() {
        return userPhone;
    }

    public void setUserPhone(long userPhone) {
        this.userPhone = userPhone;
    }

    public short getState() {
        return state;
    }

    public void setState(short state) {
        this.state = state;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Seckill getSeckill() {
        return seckill;
    }

    public void setSeckill(Seckill seckill) {
        this.seckill = seckill;
    }
}

2、DAO
SeckillDao.java

package dao;
import entity.Seckill;
import org.apache.ibatis.annotations.Param;

import java.util.Date;
import java.util.List;

/**
 * @Author:peishunwu
 * @Description:
 * @Date:Created  2018/6/1
 */
public interface SeckillDao {
    /**
     * 減庫存
     * @param seckillId
     * @param killTime
     * @return 如果影響的行數>1,表示更新行數
     */
    int reduceNumber(@Param("seckillId") long seckillId, @Param("killTime")Date killTime);

    /**
     * 根據id查詢秒殺庫存
     * @param seckillId
     * @return
     */
    Seckill gueryById(long seckillId);
    /**
     * 根據偏移量查詢秒殺列表
     * @param offset
     * @param limit
     * @return
     * 唯一形參自動賦值
     * 當有多個引數的時候要指定實際的形參名稱賦值,不然找不到對應值,因為Java並沒有儲存形參的記錄
     *java在執行的時候會把List<Seckill> queryAll(int offset,intlimit);中的引數變成這樣:queryAll(int arg0,int arg1),這樣我們就沒有辦法去傳遞多個引數
     */
    List<Seckill> queryAll(@Param("offset")int offset, @Param("limit")int limit);


}

SuccessKilledDao

package dao;

import entity.SuccessKilled;
import org.apache.ibatis.annotations.Param;

/**
 * @Author:peishunwu
 * @Description:
 * @Date:Created  2018/6/1
 */
public interface SuccessKilledDao {
    /**
     * 插入購買明細,過濾重複(聯合唯一主鍵)
     * @param seckillId
     * @param userPhone
     * @return
     */
    int insertSuccessKilled(@Param("seckillId") long seckillId,@Param("userPhone") long userPhone);

    /**
     * 根據ID查詢SuccessKilled並攜帶秒殺產品物件體
     * @param seckillId
     * @param userPhone
     * @return
     */
    SuccessKilled queryByIdWithSeckill(@Param("seckillId") long seckillId,@Param("userPhone") long userPhone);

}

四、基於mybatis的dao層實現

設計好了Database和Dao層,剩下的就是需要一個對映關係來連結兩者,將資料和物件對應起來,這時就需要Mybatis或者Hibernate來完成任務,“關係型物件對映— ORM(Object/RelationshipMapping)”的名稱也是由此而來。

Mybatis特點:
引數需要提供+SQL需要自己寫(比較靈活) = Entity/List
SQL檔案可以寫在xml檔案或者註解當中,實際使用當中提倡使用xml配置檔案來寫SQL,避免修改重新編譯類等。

如何實現DAO介面?
第一種:通過Mapper自動實現Dao層介面(推薦使用),將執行結果集封裝成我們想要的方式;
第二種:通過API程式設計的方式實現Dao介面。

1、Mybatis總配置檔案

配置檔案mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--配置全域性屬性-->
    <settings>
        <!--使用jdbc的getGeneratekeys獲取自增主鍵值-->
        <setting name="useGeneratedKeys" value="true"/>
        <!--使用列別名替換列名  預設值為true
        select name as title(實體中的屬性名是title) form table;
        開啟後mybatis會自動幫我們把表中name的值賦到對應實體的title屬性中-->
        <setting name="useColumnLabel" value="true"/>
        <!--開啟駝峰命名轉換Table:create_time到 Entity(createTime)-->
        <!-- 駝峰命名規範:Mybatis會自動轉化列屬性 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
</configuration>

<!-- 在mybatis官方文件 的入門-全域性配置-有mybatis的標準配置 -->

2、Dao配置檔案
保證Dao配置檔案和Dao層類名相同,形成一種規範。

SeckillDao.xml檔案,為Dao層定義的介面提供sql語句,Dao層的介面中的引數可以自動被Mybatis繫結到配置檔案對應的Sql語句裡面的引數,檔案內容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.seckill.dao.SeckillDao">
    <!-- 目的:為Dao層介面方法提供sql語句配置 -->
    <!-- 為第一個方法提供sql語句 -->
    <update id="reduceNumber">
        <!-- 具體sql,返回影響的行數 -->
        update seckill set number=number-1
        where seckill_id=#{seckillId}
        and start_time <![CDATA[<=]]> #{killTime}
        and end_time<![CDATA[>=]]> #{killTime}
        and number>0;           
    </update>

    <select id="queryById" resultType="Seckill" parameterType="long">
        select seckill_id,name,number,create_time,start_time,end_time
        from seckill
        where seckill_id=#{seckillId}       
    </select>

    <select id="queryAll" resultType="Seckill">
        select seckill_id,name,number,create_time,start_time,end_time
        from seckill
        order by create_time desc
        limit #{offset},#{limit} <!-- 在偏移量之後取的行數 -->        
    </select>

</mapper>

SuccessSeckilledDao.xml配置

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.seckill.dao.SuccessKilledDao">
    <insert id="insertSuccessKilled">
    <!-- 使用ignore在主鍵衝突的時候報錯返回0,避免插入數值 -->
        insert ignore into success_killed(seckill_id,user_phone,state)
        values(#{seckillId},#{userPhone},0)     
    </insert>

    <select id="queryByIdWithSeckill" resultType="SuccessKilled">
        <!-- 根據Id查詢SuccessKilled並攜帶秒殺產品物件實體。 -->
        <!-- 如何告訴Mybatis把結果對映到SuccessKilled同時對映seckill屬性 -->
        <!--級聯處理:通過別名告訴Mybatis怎麼對映到seckill實體裡面的屬性 -->
        select 
            sk.seckill_id,
            sk.user_phone,
            sk.create_time,
            sk.state,
            s.seckill_id "seckill.seckill_id", 
            s.name "seckill.name",
            s.number "seckill.number",
            s.start_time "seckill.start_time",
            s.end_time "seckill.end_time",
            s.create_time "seckill.create_time"
        from success_killed sk
        inner join seckill s on sk.seckill_id=s.seckill_id
        where sk.seckill_id=#{seckillId} and sk.user_phone=#{userPhone}
    </select>
</mapper>

五、整合Mybatis+Spring

將兩者整合是為了更好的優化程式碼,整合目標是為了更少的編碼、更少的配置、足夠的靈活

  • 更少的編碼:
    使用mybatis只用寫介面,不用寫介面的實現方法,mybatis會自動幫忙實現介面。
    看下面的一個介面與SQL語句的對應關係:
    這裡寫圖片描述
  • 更少的配置

當有很多Dao的對映檔案的時候,則需要配置很多的<mapperresource=’”mapper/SeckillDao.xml”/>,這樣會比較麻煩,對於開發人員來說是一個很重的配置維護成本,這時候使用Mybatis可以自動掃描某一個目錄下的所有以xml結尾的檔案,這樣就有了更少的配置。
另外,當有很多Dao的時候,需要配置對應的<bean id=”” class=””/>,使用mybatis則不用配置這些東西,因為mybatis可以自動實現Dao介面,自動注入Spring容器。

這體現出了使用Mybatis可以更少的對檔案進行配置。

  • 更靈活
    使用Mybatis就是因為可以自由定製SQL並且傳參,結果可以實現自動賦值,這也是為什麼Mybatis為什麼如此受歡迎的原因,整合了Spring的Mybatis仍然保持了足夠的靈活性,當我們使用這兩個技巧的時候:XML提供SQL語句和DAO介面提供Mapper,可以在Spring整合後實現,這也是我們在開發中經常推薦的方式。

整合程式碼
Spring和Mybatis整合的總體配置:(其中spring配置在Spring的官方文件裡面有介紹)
1、pom檔案增加Spring依賴和mybatis依賴mysql依賴

<?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.psw</groupId>
  <artifactId>seckill</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>seckill Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <!-- 3.0版本使用程式設計方式執行,4.0則使用註解方式 -->
      <groupId>junit</groupId><!-- 使用單元測試需要的依賴 -->
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>


    <!-- 補全專案依賴 -->
    <!-- 1:日誌 java日誌:slf4j,log4j,logback,common-logging
            slf4j是規範/介面
            日誌實現:log4j,loggback,common-logging
            使用slf4j+logback
    -->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.12</version>
    </dependency>

    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
      <version>1.1.1</version>
    </dependency>
    <!-- 實現slf4j的介面並將其整合進來 -->
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
      <version>1.1.1</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.21</version>
    </dependency>
    <dependency>
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId>
      <version>0.9.1.2</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <!-- Dao持久化層框架依賴:Mybatis依賴,即Mybatis自身的依賴和 Mybatis與Spring的整合依賴-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.2.8</version>
    </dependency>
    <!-- mybatis自身實現的spring整合依賴
        因為Mybatis的前身ibatis出現比較早,spring提供了對ibatis的依賴,但是Mybatis出現的時候,並沒有對其提供整合依賴
        所以,mybatis特意提供了對Spring的整合依賴
    -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.0</version>
    </dependency>
    <!-- 4:spring依賴 -->
    <!-- (1)Spring核心依賴 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <dependency><!-- Spring IOC擴充套件依賴 -->
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <!-- (2)Spring Dao層的依賴 -->
    <dependency><!-- Spring JDBC方面的依賴 -->
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <dependency><!-- Spring 事務方面的依賴 -->
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <!-- (3)Spring Web相關依賴 -->
    <dependency><!-- Spring web方面的依賴:專案本身是個web工程,需要經過Servlet容器去啟動 -->
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <dependency><!-- Spring MVC依賴  :MVC框架使用的是Spring MVC-->
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
    <!-- (4)Spring test方面的依賴 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>4.1.7.RELEASE</version>
    </dependency>
  </dependencies>

  <build>
    <finalName>seckill</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.0.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.7.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.20.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>
  </build>
</project>

2、資料庫配置jdbc.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://locahost:3306/seckill?useUnicode=true&characterEncoding=utf8
username=root
password=psw105

2、Spring-dao.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context-3.0.xsd" >

    <!-- 配置整合Mybatis的過程 -->
    <!-- 1:配置資料庫相關引數  properties的屬性:${url}         -->
    <context:property-placeholder location="classpath:jdbc.properties"/> <!-- 載入配置引數的檔案所在地 -->

    <!-- 2:資料庫連線池 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!-- 配置連線池屬性 -->
        <!-- c3p0連線池的基本屬性 -->
        <property name="driverClass" value="${driver}"/>
        <property name="jdbcUrl" value="${url}"/>
        <property name="user" value="${username}"/>
        <property name="password" value="${password}"/>

        <!--連線池的私有屬性根據高併發應用場景 -->
        <property name="maxPoolSize" value="30"/><!--連線池最多保留30個物件 -->
        <property name="minPoolSize" value="10"/>

        <!-- 關閉連線後不自動commit -->
        <property name="autoCommitOnClose" value="false"/>
        <!-- 獲取連線超時時間 -->
        <property name="checkoutTimeout" value="6000"/>
        <!-- 當前獲取連線失敗重試次數 -->
        <property name="acquireRetryAttempts" value="2"/>
    </bean>


    <!-- 使用框架趨勢:約定大於配置,將相應的檔案放在對應包下,通過已配置項可以自動掃描 -->
    <!-- 3:配置 SqlSessionFactory物件  真正的整合配置-->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--注入資料庫連線池  -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 配置Mybatis全域性配置檔案:mybatis-config.xml -->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <!-- 掃描entity包 使用別名org.seckill.entity -->
        <property name="typeAliasesPackage" value="entity"/>
        <!-- 掃描Sql配置檔案:mapper需要的xml檔案 -->
        <property name="mapperLocations" value="classpath:mapper/*.xml"/>
    </bean>

    <!-- 4: 配置掃描Dao介面包,動態實現Dao介面,注入到spring容器中-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--注入SqlSessionFactory 使用sqlSessionFactoryBeanName可以在用的時候再找sqlSessionFactory,防止提前初始化-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!-- 給出需要掃描Dao介面包-->
        <property name="basePackage" value="dao"/>
    </bean>

</beans>

六、單元測試

編寫兩個Dao類介面的測試類,這裡使用Junit4來進行單元測試;
1、SeckillDaoTest

package dao;


import entity.Seckill;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @Author:peishunwu
 * @Description:
 * @Date:Created  2018/6/1
 * 配置Spring和Junit整合,Junit啟動時載入SPringIOC容器
 * spring-test,junit:spring測試的依賴
 * 1:RunWith:Junit本身需要的依賴
 */
@RunWith(SpringJUnit4ClassRunner.class)
//2:告訴Junit Spring的配置檔案
@ContextConfiguration({"classpath:spring/spring-dao.xml"})
public class SeckillDaoTest {
    //3:注入Dao實現類依賴  --會自動去Spring容器中查詢seckillDao的實現類注入到單元測試類
    @Resource
    private SeckillDao seckillDao;
    @Test
    public void testQueryById()throws Exception{
        long id = 1000;
        Seckill seckill = seckillDao.queryById(id);
        System.out.println(seckill.getName());
        System.out.println(seckill);
    }

    @Test
    public void reduceNumber()throws Exception{
        long seckillId = 1000;
        Date killTime = new Date();
        int updateCount = seckillDao.reduceNumber(seckillId,killTime);
        System.out.println(updateCount);
    }

}

執行:
這裡寫圖片描述

2、SuccessKilledTest

package dao;

import entity.SuccessKilled;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.alibaba.fastjson.JSONObject;
import javax.annotation.Resource;

/**
 * @Author:peishunwu
 * @Description:
 * @Date:Created  2018/6/4
 */
@RunWith(SpringJUnit4ClassRunner.class)
/*告訴Junit Spring的配置檔案*/
@ContextConfiguration("classpath:spring/spring-dao.xml")
public class SuccessSeckillDaoTest {

    @Resource
    private SuccessKilledDao successKilledDao;
    /* 
     *inserCount=0:已經插入相同記錄 
     *inserCount=1:當前執行操作插入了一條記錄 
     */  
    @Test
    public void insertSuccess