京东秒杀之商品展示

1 在gitee上添加.yml文件

1.1 添加good-server.yml文件

server:
  port: 8084
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/shop_goods?serverTimezone=GMT%2B8
    driverClassName: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    username: root
    password: 123456
mybatis:
  configuration:
    default-fetch-size: 100
    default-statement-timeout: 3000
    map-underscore-to-camel-case: true

1.2 添加seckill-server.yml文件

在这里插入图片描述

server:
  port: 8085
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/shop_seckill?serverTimezone=GMT%2B8
    driverClassName: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    username: root
    password: 123456
mybatis:
  configuration:
    default-fetch-size: 100
    default-statement-timeout: 3000
    map-underscore-to-camel-case: true

2 创建启动类

2.1 创建商品服务启动类

@SpringBootApplication
@EnableEurekaClient
public class GoodServerApp {
    public static void main(String[] args) {
        SpringApplication.run(GoodServerApp.class, args);
    }
}

2.2 创建秒杀启动类

在这里插入图片描述

@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class SeckillServerApp {
    public static void main(String[] args) {
        SpringApplication.run(SeckillServerApp.class, args);
    }
}

3 编写前端商品页面

<!DOCTYPE html>
<html lang="en">
<head>
    <title>商品列表</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <script type="text/javascript" src="/js/jquery.min.js"></script>
    <link rel="stylesheet" type="text/css" href="/bootstrap/css/bootstrap.min.css" /><!-- bootstrap -->
    <script type="text/javascript" src="/bootstrap/js/bootstrap.min.js"></script>
    <script type="text/javascript" src="/jquery-validation/jquery.validate.min.js"></script> <!-- jquery-validator -->
    <script type="text/javascript" src="/jquery-validation/localization/messages_zh.min.js"></script>
    <script type="text/javascript" src="/layer/layer.js"></script><!-- layer -->
    <script type="text/javascript" src="/js/md5.min.js"></script><!-- md5.js -->
    <script type="text/javascript" src="/js/common.js"></script><!-- common.js -->
</head>
<body>
<div class="panel panel-default">
    <div class="panel-heading">秒杀商品列表</div>
    <table class="table" id="goodlist">
        <tr><td>商品名称</td><td>商品图片</td><td>商品原价</td><td>秒杀价</td><td>库存数量</td><td>详情</td></tr>
    </table>
</div>

<script type="text/javascript">
    String.prototype.format=function () {
        if(arguments.length==0){
            return this;
        }
        var obj=arguments[0];
        var s = this;

        for(var key in obj){
            s= s.replace(new RegExp("\\{\\{"+key+"\\}\\}","g"),obj[key]);
        }
        return s;
    };


    var template="<tr><td>{{goodName}}</td>" +
        "<td><img src='{{goodImg}}' width='100px' height='100px' /> </td>" +
        "<td>{{goodPrice}}</td>" +
        "<td>{{seckillPrice}}</td>" +
        "<td>{{stockCount}}</td>" +
        "<td> <a href='good_detail.html?seckillId={{id}}'>详情</a> </td></tr>";


    $(function () {
        $.ajax({
            url: "http://localhost:9000/seckill/seckillGood/query",
            type: "get",
            xhrFields: {withCredentials: true}, //启用cookie
            success:function (data) {
                if(data.code==200){
                    //填充表格中的数据
                    render(data.data);
                }else{
                    layer.msg(data.msg)
                }
            }
        });
    });


    function render(goodlist) {
        for(var i=0;i<goodlist.length;i++){
            $("#goodlist").append(template.format(goodlist[i]));
        }

    }
    
</script>
</body>
</html>

4 商品查询

由于在前端页面展示的信息来自不同的两张表,因此需要运用远程调用:

    1. 在单表查询 数据 t_seckill_good 数据 秒杀的商品 列表 SeckillGoodList
    1. 获取 good_id 集合 ids[1,2]
    1. 远程调用 good-server 传递参数 [1,2] 在商品表中查询 t_goods 数据 GoodList

4.1 创建实体类

1 创建商品类

@Data
public class Good implements Serializable {

    private Long id;
    private String goodName;
    private String  goodTitle;
    private String  goodImg;
    private String goodDetail;
    private BigDecimal goodPrice;
    private Integer  goodStock;
}

2 创建秒杀类

@Data
public class SeckillGoods implements Serializable {

    private Long id;
    private Long goodId;
    private BigDecimal seckillPrice;
    private Integer stockCount;
    //时间的问题后续得处理 ----
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date startDate;
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date endDate;
}

3 创建前端封装类(对应前端页面需要展示的数据)

@Data
public class SeckillGoodVo extends SeckillGood implements Serializable{

    private String goodName;
    private String  goodTitle;
    private String  goodImg;
    private String goodDetail;
    private BigDecimal goodPrice;
}

4.2 实现远程调用(通过远程调用传递的ids来查找商品信息)

1 创建断路器

public class GoodFeignHystrix implements GoodFeignApi {
    @Override
    public Result<List<Good>> queryByIds(List<Long> ids) {
        return null;
    }
}

2 创建远程调用接口

@FeignClient(name = "good-server", fallbackFactory = GoodFeignHystrix.class)
public interface GoodFeignApi {

    @RequestMapping("/queryByIds")
    public Result<List<Good>> queryByIds(@RequestParam("ids") List<Long> ids);

}

3 创建Mapper接口

@Mapper
public interface GoodMapper {

    /**
     * 根据id查询商品信息
     * @param ids
     * @return
     */
    @SelectProvider(type = GoodMapperSQLProvider.class, method = "queryByIds")
    public List<Good> queryByIds(@Param("ids") List<Long> ids);

    /**
     * 由于没有mapper的配置文件,不能使用foreach标签,因此在这里实现SQL的循环
     */
    class GoodMapperSQLProvider{
        /**
         * select * from t_goods where id in (x, x, x,....),将ids循环遍历到()内
         * @param ids
         * @return
         */
        public String queryByIds(@Param("ids") List<Long> ids){
            StringBuilder sb = new StringBuilder();

            sb.append("select * from t_goods ");
            if (ids != null || ids.size() > 0){

                sb.append(" where id in (");
                for (int i = 0; i < ids.size(); i++) {
                    if (i != 0){
                        sb.append(",");
                    }
                    sb.append(ids.get(i));
                }

                sb.append(")");
            }

            return sb.toString();
        }
    }
}

4 创建service业务逻辑接口及其实现类


service业务逻辑接口

public interface GoodService {

    /**
     * 根据id查询商品信息
     * @param ids
     * @return
     */
    public List<Good> queryByIds(List<Long> ids);
}

实现类

@Service
public class GoodServiceImpl implements GoodService {

    @Autowired
    private GoodMapper goodMapper;

    @Override
    public List<Good> queryByIds(List<Long> ids) {

        if (ids == null || ids.size() == 0){
            return Collections.emptyList();
        }

        return goodMapper.queryByIds(ids);
    }
}

5 创建controller层

@RestController
public class GoodFeignClient implements GoodFeignApi {

    @Autowired
    private GoodService goodService;
    @Override
    public Result<List<Good>> queryByIds(List<Long> ids) {
        List<Good> goodlist = goodService.queryByIds(ids);
        return Result.success(goodlist);
    }
}

4.3 数据聚合(把商品信息和秒杀信息聚合为前端页面所需的类)

1 创建秒杀的CodeMsg

public class SeckillCodeMsg extends CodeMsg {


    public SeckillCodeMsg() {
    }

    public SeckillCodeMsg(Integer code, String msg) {
        super(code, msg);
    }


    public static  final SeckillCodeMsg PRODUCT_SERVER_ERROR= new SeckillCodeMsg(500010,"商品微服务繁忙");
    public static  final SeckillCodeMsg LOGIN_TIMEOUT= new SeckillCodeMsg(500011,"登录信息过期了");
    public static  final SeckillCodeMsg OP_ERROR= new SeckillCodeMsg(500012,"非法操作");

}

2 创建Mapper接口

@Mapper
public interface SeckillGoodMapper {

    @Select("SELECT * FROM t_seckill_goods")
    public List<SeckillGood> query();
}

3 创建service业务逻辑接口及其实现类


service业务逻辑接口

public interface SeckillGoodService {

    /**
     * 查询商品数据
     * @return
     */
    public List<SeckillGoodVo> query();
}

实现类

@Service
public class SeckillGoodServiceImpl implements SeckillGoodService {

    @Autowired
    private SeckillGoodMapper seckillGoodMapper;

    @Autowired
    private GoodFeignApi goodFeignApi;

    @Override
    public List<SeckillGoodVo> query() {
        //1. 单表查询 数据 t_seckill_good 数据 秒杀的商品 列表  SeckillGoodList
        List<SeckillGood> seckillGoodList = seckillGoodMapper.query();
        //2. 获取 good_id 集合 ids[1,2]

        //3  远程调用 good-server   传递参数 [1,2] 在商品表中查询   t_goods 数据 GoodList
        List<SeckillGoodVo> seckillGoodVoList = getSeckillGoodVos(seckillGoodList);


        return seckillGoodVoList;
    }

    /**
     * 获取秒杀商品列表
     *
     * @param seckillGoodList
     * @return
     */
    private List<SeckillGoodVo> getSeckillGoodVos(List<SeckillGood> seckillGoodList) {
        //利用set集合来进行数据去重
        Set<Long> idSet = new HashSet<>();
        for (SeckillGood seckillGood : seckillGoodList) {
            //去除重复的goodid
            idSet.add(seckillGood.getGoodId());
        }

        List<Long> ids = new ArrayList<>(idSet);
        //远程调用获取商品信息
        Result<List<Good>> result = goodFeignApi.queryByIds(ids);

        //远程调用失败
        if (result == null || result.hasError()) {
            throw new BusinessException(SeckillCodeMsg.PRODUCT_SERVER_ERROR);
        }

        //远程调用成功
        List<Good> goodList = result.getData();

        //获取商品信息存到Map中
        Map<Long, Good> goodMap = new HashMap<>();
        for (Good good : goodList) {
            goodMap.put(good.getId(), good);
        }

        //将商品信息和秒杀信息聚合
        List<SeckillGoodVo> seckillGoodVoList = new ArrayList<>();

        for (SeckillGood seckillGood : seckillGoodList) {
            //获取商品
            Good good = goodMap.get(seckillGood.getGoodId());

            //聚合
            SeckillGoodVo vo = new SeckillGoodVo();
            vo.setGoodDetail(good.getGoodDetail());
            vo.setGoodImg(good.getGoodImg());
            vo.setGoodName(good.getGoodName());
            vo.setGoodPrice(good.getGoodPrice());
            vo.setGoodTitle(good.getGoodTitle());
            //秒杀的结束时间
            vo.setEndDate(seckillGood.getEndDate());
            vo.setGoodId(good.getId());
            vo.setId(seckillGood.getId());//场次id
            vo.setStartDate(seckillGood.getStartDate());//秒杀开始时间
            vo.setStockCount(seckillGood.getStockCount());//秒杀商品的数量
            vo.setSeckillPrice(seckillGood.getSeckillPrice());//秒杀价格
            //添加到集合中
            seckillGoodVoList.add(vo);

        }
        return seckillGoodVoList;
    }
}

4 创建controller层

@RestController
@RequestMapping("/seckillGood")
public class SeckillGoodController {

    @Autowired
    private SeckillGoodService seckillGoodService;

    @RequestMapping("/query")
    public Result query(){

        List<SeckillGoodVo> seckillGoodVoList = seckillGoodService.query();
        return Result.success(seckillGoodVoList);
    }
}

4.4 登录测试

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/196589.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

自动驾驶HWP功能规范

HWP功能规范 Highway Pilot Functional Specification 文件状态&#xff1a; 【√】草稿 【】正式发布 【】正在修改 文件起草分工 撰写&#xff1a; 审核&#xff1a; 编制&#xff1a; 签名&#xff1a; 日期&#xff1a; 审核&#xff1a; 签名&#xff1a; 日期&am…

抖音视频如何无水印下载,怎么批量保存主页所有视频没水印?

现在最火的短视频平台莫过于抖音&#xff0c;当我们刷到一个视频想下载下来怎么办&#xff1f;我们知道可以通过保存到相册的方式下载&#xff0c;但用这种方法下载的视频带有水印&#xff0c;而且有些视频不能保存到相册&#xff08;这是视频作者设置了禁止下载&#xff09;。…

c# 简单web api接口实例源码分析

CreateHostBuilder(args).Build().Run();这句语句处于c#webapi程序的第一句&#xff0c;它的作用是&#xff1a;启动接口的三个步骤&#xff1a; 创建一个HostBuilder对象。执行IHostBuilder.Build()方法创建IHost对象。执行IHost.Run()方法启动。 创建和配置Host&#xff08;…

蚁剑低版本反制

蚁剑低版本反制 漏洞概述 中国蚁剑是一款开源的跨平台网站管理工具&#xff0c;它主要面向于合法授权的渗透测试安全人员以及进行常规操作的网站管理员。影响范围 AntSword <2.0.7 蚁剑实验版本&#xff1a;2.0.7 环境搭建&#xff1a; 172.16.1.233&#xff08;蓝队服…

【Python深度学习第二版】学习笔记之——什么是深度学习

机器学习是将输入&#xff08;比如图像&#xff09;映射到目标&#xff08;比如标签“猫”&#xff09;的过程。 这一过程是通过观察许多输入和目标的示例来完成的。 深度神经网络通过一系列简单的数据变换&#xff08;层&#xff09;来实现这种输入到目标的映射&#xff0c;这…

解读 | 从谷歌AI判定阿波罗登月“造假“来谈谈合成图片检测技术

大家好&#xff0c;我是极智视界&#xff0c;欢迎关注我的公众号&#xff0c;获取我的更多前沿科技分享 邀您加入我的知识星球「极智视界」&#xff0c;星球内有超多好玩的项目实战源码和资源下载&#xff0c;链接&#xff1a;https://t.zsxq.com/0aiNxERDq 整个事情可以爬楼看…

【2023.11.28】关于Servlet路径的学习

创建Servlet 这是Tomcat配置的初始路径&#xff0c;在web项目内&#xff0c;该路径代表了webapp下index.html所在的页面。 WebServlet(name "login", value "/login",loadOnStartup 1) public class LoginServlet extends HttpServlet { 使用注解的方…

leetcode:2133. 检查是否每一行每一列都包含全部整数(python3解法)

难度&#xff1a;简单 对一个大小为 n x n 的矩阵而言&#xff0c;如果其每一行和每一列都包含从 1 到 n 的 全部 整数&#xff08;含 1 和 n&#xff09;&#xff0c;则认为该矩阵是一个 有效 矩阵。 给你一个大小为 n x n 的整数矩阵 matrix &#xff0c;请你判断矩阵是否为一…

算法效率的度量

算法效率的度量通常是通过时间复杂度和空间复杂度来描述的。 一、时间复杂度 算法中所有语句的执行次数之和为T(n)&#xff0c;它是算法问题规模n的函数&#xff0c;时间复杂度主要分析T(n)的数量级。 分类 1. 最好时间复杂度&#xff1a;最好情况下&#xff0c;算法的时间…

国自然项目基金撰写及技巧

随着社会经济发展和科技进步&#xff0c;基金项目对创新性的要求越来越高。申请人需要提出独特且有前瞻性的研究问题&#xff0c;具备突破性的科学思路和方法。因此&#xff0c;基金项目申请往往需要进行跨学科的技术融合。申请人需要与不同领域结合&#xff0c;形成多学科交叉…

智能优化算法应用:基于飞蛾扑火算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于飞蛾扑火算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于飞蛾扑火算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.飞蛾扑火算法4.实验参数设定5.算法结果6.参考…

算法之插入排序及希尔排序(C语言版)

我们来实现上述排序 一.插入排序. 当插入第i(i>1)个元素时&#xff0c;前面的array[0],array[1],.,array[i-1]已经排好序&#xff0c;此时用array[i的排序码与array[i-1]array[i-2].的排序码顺序进行比较&#xff0c;找到插入位置即将arrayU插入&#xff0c;原来位置上的元…

【RTP】4: 实例解析:一个SRTP的wireshark抓包:带padding、带扩展

抓取的是视频包。固定的pt是127从头部找到序号,快速找到这个包包大小因为是包括了SRTP的,所以318 个字节,实际RTP包是286个字节。SRTP 包 UDP总共 294个字节,payload部分286 RTP协议 RTP部分: B0 代表有padding、有扩展 从B0开始

【Linux】gcc和g++

&#x1f466;个人主页&#xff1a;Weraphael ✍&#x1f3fb;作者简介&#xff1a;目前正在学习c和Linux还有算法 ✈️专栏&#xff1a;Linux &#x1f40b; 希望大家多多支持&#xff0c;咱一起进步&#xff01;&#x1f601; 如果文章有啥瑕疵&#xff0c;希望大佬指点一二 …

linux shell操作 - 05 进程 与 IO 模型

文章目录 计算机内存分配进程与子进程流IO模型非阻塞IOIO多路复用网络IO模型简单的socket并发的socket 计算机内存分配 一个32位&#xff0c;4G内存的计算机&#xff0c;内存使用分为两部分&#xff1a; 操作系统内核空间&#xff1b;应用程序的用户空间使用的操作系统不同&a…

如何使用低代码平台加速应用开发?

目录 一、背景 二、低代码开发和传统开发的区别 1.低代码开发方式能够实现业务应用的快速交付 2.低代码开发平台还能够降低业务应用的开发成本 三、低代码开发对你有什么帮助&#xff1f; 四、低代码工具的使用者是谁&#xff1f; 五、典型的低代码开发平台有哪些&#xff1f…

02-鸿蒙学习之4.0todoList练习

02-鸿蒙学习之4.0todoList练习 代码 /*** 1:组件必须使用Component装饰* 2.Entry 装饰哪个组件&#xff0c;哪个组件就呈现在页面上* 3.被Entry 装饰的入口组件。build&#xff08;&#xff09;必须有且仅有一个根 ** 容器 ** 组件* 其他的自定义组件&#xff0c;build() 中…

一篇总结 Linux 系统启动的几个汇编指令

学习 Linux 系统启动流程&#xff0c;必须熟悉几个汇编指令&#xff0c;总结给大家。 这里不是最全的&#xff0c;只列出一些最常用的汇编指令。 一&#xff0e;数据处理指令 1.数据传送指令 【MOV指令】 把一个寄存器的值(立即数)赋给另一个寄存器&#xff0c;或者将一个…

spring boot 整合 spring security

项目结构 添加依赖 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.9.RELEASE</version><relativePath/></parent><dependency><grou…

leetcode刷题详解十

188. 买卖股票的最佳时机 IV&#xff08;最多买卖k次&#xff09; 注意事项 这道题和最多买卖两次是一模一样的思路就是把2换成k了但是还是有几个地方需要注意的 给的整数数组可能为0k其实没有很大&#xff0c;可以想一下&#xff0c;最多为n/2(n是数组的长度) int maxProfit…