文章目录
1.数据库表设计 1.商品表 2.秒杀商品表 3.修改一下秒杀时间为今天到明天
2.pojo和vo编写 1.com/sxs/seckill/pojo/Goods.java 2.com/sxs/seckill/pojo/SeckillGoods.java 3.com/sxs/seckill/vo/GoodsVo.java
3.Mapper编写 1.GoodsMapper.java 2.GoodsMapper.xml 3.分别编写SeckillGoodsMapper.java和SeckillGoodsMapper.xml
4.Service编写 1.GoodsService.java 2.GoodsServiceImpl.java 3.分别编写SeckillGoodsService.java和SeckillGoodsServiceImpl.java
5.Controller编写
6.展示商品列表页 1.goodsList.html 2.测试使用 1.报错,GoodsService没被注入 2.加一下Service注解即可 3.登录成功 4.访问 http://localhost:9092/seckill/goods/toList 没有图片 5.把图片放到imgs下即可 6.重新访问
3.调整templates/login.html 登录成功后直接跳转到商品列表页
7.商品详情页 1.Mapper编写 根据商品id获取商品详情 1.GoodsMapper.java 2.GoodsMapper.xml
2.Service编写 1.GoodsService.java 2.GoodsServiceImpl.java
3.Controller编写
4.前端界面编写 1.goodsList.html 修改请求(使用环境变量+资源路径的形式) 2.goodsDetail.html 商品详情页
5.测试
1.数据库表设计
1.商品表
use seckill;
DROP TABLE IF EXISTS ` t_goods` ;
CREATE TABLE ` t_goods`
(
` id` BIGINT ( 20 ) NOT NULL AUTO_INCREMENT COMMENT '商品 id' ,
` goods_name` VARCHAR ( 16 ) not null DEFAULT '' ,
` goods_title` VARCHAR ( 64 ) not null DEFAULT '' COMMENT '商品标题' ,
` goods_img` VARCHAR ( 64 ) not null DEFAULT '' COMMENT '商品图片' ,
` goods_detail` LONGTEXT not null COMMENT '商品详情' ,
` goods_price` DECIMAL ( 10 , 2 ) DEFAULT '0.00' COMMENT '商品价格' ,
` goods_stock` INT ( 11 ) DEFAULT '0' COMMENT '商品库存' ,
PRIMARY KEY ( ` id` )
) ENGINE = INNODB
AUTO_INCREMENT = 3
DEFAULT CHARSET = utf8mb4;
INSERT INTO ` t_goods`
VALUES ( '1' , '整体厨房设计-套件' , '整体厨房设计-套件' , '/imgs/kitchen.jpg' , '整体厨房设计-套件' , '15266.00' , '100' ) ;
INSERT INTO ` t_goods`
VALUES ( '2' , '学习书桌-套件' , '学习书桌-套件' , '/imgs/desk.jpg' , '学习书桌-套件' , '5690.00' , '100' ) ;
select * from t_goods;
2.秒杀商品表
use seckill;
DROP TABLE IF EXISTS ` t_seckill_goods` ;
CREATE TABLE ` t_seckill_goods`
(
` id` BIGINT ( 20 ) NOT NULL AUTO_INCREMENT ,
` goods_id` BIGINT ( 20 ) DEFAULT 0 ,
` seckill_price` DECIMAL ( 10 , 2 ) DEFAULT '0.00' ,
` stock_count` INT ( 10 ) DEFAULT 0 ,
` start_date` DATETIME DEFAULT NULL ,
` end_date` DATETIME DEFAULT NULL ,
PRIMARY KEY ( ` id` )
) ENGINE = INNODB
AUTO_INCREMENT = 3
DEFAULT CHARSET = utf8mb4;
INSERT INTO ` t_seckill_goods`
VALUES ( '1' , '1' , '5266.00' , '10' , '2022-11-18 19:36:00' , '2022-11-19 09:00:00' ) ;
INSERT INTO ` t_seckill_goods`
VALUES ( '2' , '2' , '690.00' , '10' , '2022-11-18 08:00:00' , '2022-11-19 09:00:00' ) ;
select * from t_seckill_goods;
3.修改一下秒杀时间为今天到明天
2.pojo和vo编写
1.com/sxs/seckill/pojo/Goods.java
package com. sxs. seckill. pojo ;
import com. baomidou. mybatisplus. annotation. IdType ;
import com. baomidou. mybatisplus. annotation. TableId ;
import com. baomidou. mybatisplus. annotation. TableName ;
import lombok. Data ;
import java. io. Serializable ;
import java. math. BigDecimal ;
@Data
@TableName ( "t_goods" )
public class Goods implements Serializable {
private static final long serialVersionUID = 1L ;
@TableId ( value = "id" , type = IdType . AUTO )
private Long id;
private String goodsName;
private String goodsTitle;
private String goodsImg;
private String goodsDetail;
private BigDecimal goodsPrice;
private Integer goodsStock;
}
2.com/sxs/seckill/pojo/SeckillGoods.java
package com. sxs. seckill. pojo ;
import com. baomidou. mybatisplus. annotation. IdType ;
import com. baomidou. mybatisplus. annotation. TableId ;
import com. baomidou. mybatisplus. annotation. TableName ;
import lombok. Data ;
import java. io. Serializable ;
import java. math. BigDecimal ;
import java. util. Date ;
@Data
@TableName ( "t_seckill_goods" )
public class SeckillGoods implements Serializable {
private static final long serialVersionUID = 1L ;
@TableId ( value = "id" , type = IdType . AUTO )
private Long id;
private Long goodsId;
private BigDecimal seckillPrice;
private Integer stockCount;
private Date startDate;
private Date endDate;
}
3.com/sxs/seckill/vo/GoodsVo.java
package com. sxs. seckill. vo ;
import com. sxs. seckill. pojo. Goods ;
import lombok. AllArgsConstructor ;
import lombok. Data ;
import lombok. NoArgsConstructor ;
import java. math. BigDecimal ;
import java. util. Date ;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class GoodsVo extends Goods {
private BigDecimal seckillPrice;
private Integer stockCount;
private Date startDate;
private Date endDate;
}
3.Mapper编写
1.GoodsMapper.java
package com. sxs. seckill. mapper ;
import com. baomidou. mybatisplus. core. mapper. BaseMapper ;
import com. sxs. seckill. pojo. Goods ;
import com. sxs. seckill. vo. GoodsVo ;
import org. apache. ibatis. annotations. Mapper ;
import java. util. List ;
@Mapper
public interface GoodsMapper extends BaseMapper < Goods > {
List < GoodsVo > findGoodsVo ( ) ;
}
2.GoodsMapper.xml
resultType为GoodsVo,则可以自动按照驼峰命名法进行匹配
<?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 = " com.sxs.seckill.mapper.GoodsMapper" >
< select id = " findGoodsVo" resultType = " com.sxs.seckill.vo.GoodsVo" >
select g.id,
g.goods_name,
g.goods_title,
g.goods_img,
g.goods_detail,
g.goods_price,
g.goods_stock,
t_seckill_goods.seckill_price,
t_seckill_goods.stock_count,
t_seckill_goods.start_date,
t_seckill_goods.end_date
from t_goods g
left join t_seckill_goods on g.id = t_seckill_goods.goods_id;
</ select>
</ mapper>
3.分别编写SeckillGoodsMapper.java和SeckillGoodsMapper.xml
4.Service编写
1.GoodsService.java
package com. sxs. seckill. service ;
import com. baomidou. mybatisplus. extension. service. IService ;
import com. sxs. seckill. pojo. Goods ;
import com. sxs. seckill. vo. GoodsVo ;
import java. util. List ;
public interface GoodsService extends IService < Goods > {
List < GoodsVo > findGoodsVo ( ) ;
}
2.GoodsServiceImpl.java
package com. sxs. seckill. service. impl ;
import com. baomidou. mybatisplus. extension. service. impl. ServiceImpl ;
import com. sxs. seckill. mapper. GoodsMapper ;
import com. sxs. seckill. pojo. Goods ;
import com. sxs. seckill. service. GoodsService ;
import com. sxs. seckill. vo. GoodsVo ;
import javax. annotation. Resource ;
import java. util. List ;
public class GoodsServiceImpl extends ServiceImpl < GoodsMapper , Goods > implements GoodsService {
@Resource
private GoodsMapper goodsMapper;
@Override
public List < GoodsVo > findGoodsVo ( ) {
return goodsMapper. findGoodsVo ( ) ;
}
}
3.分别编写SeckillGoodsService.java和SeckillGoodsServiceImpl.java
5.Controller编写
1.GoodsController.java
6.展示商品列表页
1.goodsList.html
< html lang = " en" xmlns: th= " http://www.thymeleaf.org" >
< head>
< meta charset = " UTF-8" >
< title> 商品列表</ title>
< link rel = " stylesheet" type = " text/css" th: href= " @{/bootstrap/css/bootstrap.min.css}" />
< script type = " text/javascript" th: src= " @{/js/jquery.min.js}" > </ script>
< script type = " text/javascript" th: src= " @{/jquery-validation/jquery.validate.min.js}" > </ script>
< script type = " text/javascript"
th: src= " @{/jquery-validation/localization/messages_zh.min.js}" > </ script>
< script type = " text/javascript" th: src= " @{/layer/layer.js}" > </ script>
< script type = " text/javascript" th: src= " @{/js/md5.min.js}" > </ script>
< script type = " text/javascript" th: src= " @{/js/common.js}" > </ script>
< style>
* {
margin : 0;
padding : 0;
font-family : "Open Sans" , sans-serif;
text-transform : uppercase;
letter-spacing : 3px;
font-size : 11px;
}
body {
background : #c9302c;
}
.main-header {
width : 100%;
height : 100px;
background : whitesmoke;
display : block;
}
.navbar {
display : inline-block;
float : right;
margin-right : 50px;
margin-top : 30px;
}
.logo {
display : inline-block;
margin-top : 30px;
margin-left : 30px;
text-decoration : none;
}
.logo-lg {
font-size : 20px;
font-weight : lighter;
color : #232324;
}
.logo-lg > b {
font-size : 20px;
font-weight : lighter;
color : #232324;
}
.container {
background : #FFFFFF;
}
.add-good {
padding-top : 12px;
padding-bottom : 20px;
border-radius : 10px;
outline : none;
display : block;
margin-right : 30px;
background : #f6f6f6;
color : #ce7d88;
border : solid 1px #eac7cc;
}
</ style>
</ head>
< body>
< header id = " site-header" class = " main-header" >
< a class = " logo" th: href= " @{/goods/toList}" >
< span class = " logo-lg" > < b> 商品抢购</ b> </ span> </ a>
< nav class = " navbar navbar-static-top" >
< a href = " #" class = " sidebar-toggle" data-toggle = " push-menu" role = " button" >
< span class = " sr-only" > Toggle navigation</ span>
< span class = " icon-bar" > </ span>
< span class = " icon-bar" > </ span>
< span class = " icon-bar" > </ span>
</ a>
< div class = " navbar-custom-menu" >
< ul class = " nav navbar-nav" >
< li class = " dropdown user user-menu" >
< a href = " #" class = " dropdown-toggle" data-toggle = " dropdown" >
< img class = " user-image" src = " /imgs/user.png" height = " 42" alt = " User
Image" >
< span class = " hidden-xs" > </ span>
</ a>
< ul class = " dropdown-menu" >
< li class = " user-header" >
< img class = " img-circle" alt = " User Image" >
< p>
Hello ABC - Hello ABC
< small> Hello ABC</ small>
</ p>
</ li>
< li class = " user-body" >
</ li>
< li class = " user-footer" >
< div class = " pull-middle" >
< a th: href= " @{/login/out}" class = " btn btn-lg btn-default
btn-block" > 退出系统</ a>
</ div>
</ li>
</ ul>
</ li>
</ ul>
</ div>
</ nav>
</ header>
< div class = " container" >
< 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,goodstStat : ${goodsList}" >
< td th: text= " ${goods.goodsName}" > </ td>
< td> < img th: src= " @{${goods.goodsImg}}" width = " 100" height = " 100" />
</ td>
< td th: text= " ${goods.goodsPrice}" > </ td>
< td th: text= " ${goods.seckillPrice}" > </ td>
< td th: text= " ${goods.stockCount}" > </ td>
< td> < a th: href= " ' /goods/toDetail/'+${goods.id}" > 查看详情</ a> </ td>
</ tr>
</ table>
</ div>
< script>
</ script>
2.测试使用
1.报错,GoodsService没被注入
2.加一下Service注解即可
3.登录成功
4.访问 http://localhost:9092/seckill/goods/toList 没有图片
5.把图片放到imgs下即可
6.重新访问
3.调整templates/login.html 登录成功后直接跳转到商品列表页
1.新增超链接
2.登录成功后自动跳转
7.商品详情页
1.Mapper编写 根据商品id获取商品详情
1.GoodsMapper.java
GoodsVo findGoodsVoByGoodsId ( Long goodsId) ;
2.GoodsMapper.xml
< select id = " findGoodsVoByGoodsId" resultType = " com.sxs.seckill.vo.GoodsVo" >
select g.id,
g.goods_name,
g.goods_title,
g.goods_img,
g.goods_detail,
g.goods_price,
g.goods_stock,
t_seckill_goods.seckill_price,
t_seckill_goods.stock_count,
t_seckill_goods.start_date,
t_seckill_goods.end_date
from t_goods g
left join t_seckill_goods on g.id = t_seckill_goods.goods_id
where g.id = #{goodsId};
</ select>
2.Service编写
1.GoodsService.java
GoodsVo findGoodsVoByGoodsId ( Long goodsId) ;
2.GoodsServiceImpl.java
@Override
public GoodsVo findGoodsVoByGoodsId ( Long goodsId) {
return goodsMapper. findGoodsVoByGoodsId ( goodsId) ;
}
3.Controller编写
GoodsController.java
@RequestMapping ( "/toDetail/{goodsId}" )
public String toDetail ( Model model, User user, @PathVariable Long goodsId) {
if ( null == user) {
return "login" ;
}
model. addAttribute ( "goods" , goodsService. findGoodsVoByGoodsId ( goodsId) ) ;
model. addAttribute ( "user" , user) ;
return "goodsDetail" ;
}
4.前端界面编写
1.goodsList.html 修改请求(使用环境变量+资源路径的形式)
2.goodsDetail.html 商品详情页
<! DOCTYPE html >
< html lang = " en" xmlns: th= " http://www.thymeleaf.org" >
< head>
< meta charset = " UTF-8" >
< title> 商品详情</ title>
< script type = " text/javascript" th: src= " @{/js/jquery.min.js}" > </ script>
< link rel = " stylesheet" type = " text/css" th: href= " @{/bootstrap/css/bootstrap.min.css}" />
< script type = " text/javascript" th: src= " @{/bootstrap/js/bootstrap.js}" > </ script>
< script type = " text/javascript" th: src= " @{/layer/layer.js}" > </ script>
< script type = " text/javascript" th: src= " @{/js/common.js}" > </ script>
< style>
* {
margin : 0;
padding : 0;
font-family : "Open Sans" , sans-serif;
text-transform : uppercase;
letter-spacing : 3px;
font-size : 11px;
}
body {
background : #c9302c;
}
.main-header {
width : 100%;
height : 100px;
background : whitesmoke;
display : block;
}
.navbar {
display : inline-block;
float : right;
margin-right : 50px;
margin-top : 30px;
}
.logo {
display : inline-block;
margin-top : 30px;
margin-left : 30px;
text-decoration : none;
}
.logo-lg {
font-size : 20px;
font-weight : lighter;
color : #232324;
}
.logo-lg > b {
font-size : 20px;
font-weight : lighter;
color : #232324;
}
.container {
background : #FFFFFF;
margin-right : auto;
margin-left : auto;
width : 900px;
}
.captcha {
display : none;
}
.captchaImg {
display : none;
width : 130px;
height : 32px;
}
</ style>
</ head>
< body>
< header id = " site-header" class = " main-header" >
< a class = " logo" onclick = " toList ( ) " >
< span class = " logo-lg" > < b> 商品抢购</ b> </ span>
</ a>
< nav class = " navbar navbar-static-top" >
< a href = " #" class = " sidebar-toggle" data-toggle = " push-menu" role = " button" >
< span class = " sr-only" > Toggle navigation</ span>
< span class = " icon-bar" > </ span>
< span class = " icon-bar" > </ span>
< span class = " icon-bar" > </ span>
</ a>
< div class = " navbar-custom-menu" >
< ul class = " nav navbar-nav" >
< li class = " dropdown user user-menu" >
< a href = " #" class = " dropdown-toggle" data-toggle = " dropdown" >
< img class = " user-image" src = " /imgs/user.png" height = " 32" alt = " User
Image" >
< span class = " hidden-xs" > </ span>
</ a>
< ul class = " dropdown-menu" >
< li class = " user-header" >
< img class = " img-circle" alt = " User Image" >
< p>
Hello ABC - Hello ABC
< small> Hello ABC</ small>
</ p>
</ li>
< li class = " user-body" >
</ li>
< li class = " user-footer" >
< div class = " pull-middle" >
< a onclick = " toOut ( ) " class = " btn btn-lg btn-default btn-block" > 退
出系统</ a>
</ div>
</ li>
</ ul>
</ li>
</ ul>
</ div>
</ nav>
</ header>
< div class = " panel panel-default" >
< div class = " panel-heading" style = " background : #c9302c; color : white" > 秒杀商品详情</ div>
< div class = " panel-body" >
< span th: if= " ${user eq null}" > 您还没有登录,请登陆后再操作< br/> </ span>
< span> production 参数</ span>
</ div>
< div class = " container" >
< table class = " table" id = " good" >
< tr>
< td> 名称</ td>
< td colspan = " 3" id = " goodName" th: text= " ${goods.goodsName}" > </ td>
</ tr>
< tr>
< td> 图片</ td>
< td colspan = " 3" > < img id = " goodImg" th: src= " @{${goods.goodsImg}}" width = " 200" heights = " 200" /> </ td>
</ tr>
< tr>
< td> 秒杀价</ td>
< td id = " secKillPrice" th: text= " ${goods.seckillPrice}" > </ td>
< td>
< img id = " captchaImg" class = " captchaImg" /> </ td>
< td>
< input id = " captcha" class = " captchaImg" />
< input type = " button" id = " captchabtn" onclick = " verifyCaptcha ( ) " value = " 验证
输入的验证码是否正确" >
</ td>
</ tr>
< tr>
< td> 原价</ td>
< td colspan = " 3" id = " goodPrice" th: text= " ${goods.goodsPrice}" > </ td>
</ tr>
< tr>
< td> 库存</ td>
< td colspan = " 3" id = " stockCount" th: text= " ${goods.stockCount}" > </ td>
</ tr>
</ table>
</ div>
</ div>
</ body>
< script>
</ script>
</ html>
5.测试
1.点击查看详情
2.数据正常展示