文章目录 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_datefrom t_goods gleft 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_datefrom t_goods gleft join t_seckill_goods on g.id = t_seckill_goods.goods_idwhere 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.数据正常展示