1、先創建商品的服務類GoodsService ,注入GoodsDao
@Service
public class GoodsService {
public static final String COOKIE1_NAME_TOKEN="token";
@Autowired
GoodsDao goodsDao;
@Autowired
RedisService redisService;
//獲取商品信息列表
public List<GoodsVo> getGoodsVoList() {
return goodsDao.getGoodsVoList();
}
//獲取商品根據商品Id
public GoodsVo getGoodsVoByGoodsId(long goodsId) {
return goodsDao.getGoodsVoByGoodsId(goodsId);
}
//減少商品的庫存
public void reduceStock(GoodsVo goodsvo) {
MiaoshaGoods goods=new MiaoshaGoods();
goods.setGoodsId(goodsvo.getId());
//goods.setStockCount(goodsvo.getGoodsStock()-1); sql裏面去運算
//goodsDao.reduceStock(goods.getGoodsId());
goodsDao.reduceStock(goods);
}
}
2、創建GoodsDao
注意:這裏我們查數據庫的時候,不只是查找的商品的信息,我們同時想把商品的秒殺信息也一起查出來,但是這兩個不同數據在兩個表裏面,我們就想辦法封裝一個GoodsVo,將兩張表的數據封裝到一起。
下面是GoodsVo對象,因爲繼承Goods,擁有Goods的所有字段
然後再自己定義MiaoshaGoods裏面的字段,最終拼接成一個GoodsVo對象。
//將Goods表和MiaoshaGoods表合併
public class GoodsVo extends Goods{
private Integer stockCount;
private Date startDate;
private Date endDate;
private Double miaoshaPrice;
public Double getMiaoshaPrice() {
return miaoshaPrice;
}
public void setMiaoshaPrice(Double miaoshaPrice) {
this.miaoshaPrice = miaoshaPrice;
}
public Integer getStockCount() {
return stockCount;
}
public void setStockCount(Integer stockCount) {
this.stockCount = stockCount;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
}
這裏是將兩個表做連接查詢(miaosha_goods mg left join goods g),我們需要查找的數據庫表裏面的各個字段對應到我們GoodsVo裏面的屬性,那麼就可以給其賦值。
g.*,mg.stock_count,mg.start_date,mg.end_date,mg.miaosha_price:代表goods 表裏面的所有字段加上miaosha_goods裏面的stock_count,start_date,end_date,miaosha_price
注意:使用註解@Param(“goodsId”)指定@Select語句中的#{goodsId}字段,一一對應起來
@Mapper
public interface GoodsDao {
//兩個查詢
@Select("select g.*,mg.stock_count,mg.start_date,mg.end_date,mg.miaosha_price from miaosha_goods mg left join goods g on mg.goods_id=g.id")
public List<GoodsVo> getGoodsVoList();
@Select("select g.*,mg.stock_count,mg.start_date,mg.end_date,mg.miaosha_price from miaosha_goods mg left join goods g on mg.goods_id=g.id where g.id=#{goodsId}")
public GoodsVo getGoodsVoByGoodsId(@Param("goodsId")long goodsId);
//stock_count>0的時候纔去更新,數據庫本身會有鎖,那麼就不會在數據庫中同時多個線程更新一條記錄,使用數據庫特性來保證超賣的問題
@Update("update miaosha_goods set stock_count=stock_count-1 where goods_id=#{goodsId} and stock_count>0")
public void reduceStock(MiaoshaGoods goods);
}
}
3、前端goods_list.html頁面代碼:
<!DOCTYPE html>
<!-- 使用thymeleaf,配置相應的 -->
<html xmlns:th="http://www.thymeleaf.org"> <!-- th!!! 命名空間使用 -->
<head>
<meta charset="UTF-8"/><!--<meta charset="UTF-8" /> thymeleaf模板引擎默認是Template modes:HTML5解析的,所以解析比較嚴格。 -->
<title>商品詳情</title>
<!-- thymeleaf引入靜態資源的方式,@加大括弧 "/" 代表static路徑-->
<!-- jquery -->
<!-- <script type="text/javascript" th:src="@{/js/jequery.min.js}"></script> -->
<script type="text/javascript" th:src="@{/jquery-validation/lib/jquery-1.11.1.js}"></script>
<!-- bootstrap -->
<!-- <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css" integrity="sha384-9gVQ4dYFwwWSjIDZnLEWnxCjeSWFphJiwGPXr1jddIhOegiu1FwO5qRGvFXOdJZ4" crossorigin="anonymous"/>
-->
<link type="text/css" rel="stylesheet" th:href="@{/bootstrap/css/bootstrap.css}"/>
<script type="text/javascript" th:src="@{/bootstrap/js/bootstrap.min.js}"></script>
</head>
<body>
<div class="panel panel-default">
<div class="panel-heading">秒殺商品列表</div>
<table class="table" id="goodslist">
<tr><td>商品名稱</td><td>商品圖片</td><td>商品原價</td><td>秒殺價</td><td>庫存數量</td><td>詳情</td></tr>
<tr th:each="goods,goodsStat:${goodsList}">
<td th:text="${goods.goodsName}"></td>
<td><img th:src="@{${goods.goodsImg}}" width="80" height="60"></img></td>
<td th:text="${goods.goodsPrice}"></td>
<td th:text="${goods.miaoshaPrice}"></td>
<td th:text="${goods.stockCount}"></td>
<td><a th:href="'/goods/to_detail/'+${goods.id}">詳情</a></td>
</tr>
</table>
</div>
</body>
</html>
4、效果