京东秒杀之商品展示

1 在gitee上添加.yml文件

1.1 添加good-server.yml文件

server:port: 8084
spring:datasource:url: jdbc:mysql://localhost:3306/shop_goods?serverTimezone=GMT%2B8driverClassName: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSourceusername: rootpassword: 123456
mybatis:configuration:default-fetch-size: 100default-statement-timeout: 3000map-underscore-to-camel-case: true

1.2 添加seckill-server.yml文件

在这里插入图片描述

server:port: 8085
spring:datasource:url: jdbc:mysql://localhost:3306/shop_seckill?serverTimezone=GMT%2B8driverClassName: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSourceusername: rootpassword: 123456
mybatis:configuration:default-fetch-size: 100default-statement-timeout: 3000map-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}, //启用cookiesuccess: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 {@Overridepublic 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 {@Autowiredprivate GoodMapper goodMapper;@Overridepublic 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 {@Autowiredprivate GoodService goodService;@Overridepublic 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 {@Autowiredprivate SeckillGoodMapper seckillGoodMapper;@Autowiredprivate GoodFeignApi goodFeignApi;@Overridepublic List<SeckillGoodVo> query() {//1. 单表查询 数据 t_seckill_good 数据 秒杀的商品 列表  SeckillGoodListList<SeckillGood> seckillGoodList = seckillGoodMapper.query();//2. 获取 good_id 集合 ids[1,2]//3  远程调用 good-server   传递参数 [1,2] 在商品表中查询   t_goods 数据 GoodListList<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) {//去除重复的goodididSet.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());//场次idvo.setStartDate(seckillGood.getStartDate());//秒杀开始时间vo.setStockCount(seckillGood.getStockCount());//秒杀商品的数量vo.setSeckillPrice(seckillGood.getSeckillPrice());//秒杀价格//添加到集合中seckillGoodVoList.add(vo);}return seckillGoodVoList;}
}

4 创建controller层

@RestController
@RequestMapping("/seckillGood")
public class SeckillGoodController {@Autowiredprivate SeckillGoodService seckillGoodService;@RequestMapping("/query")public Result query(){List<SeckillGoodVo> seckillGoodVoList = seckillGoodService.query();return Result.success(seckillGoodVoList);}
}

4.4 登录测试

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL 查询优化的 10 个案例!

在应用开发的早期&#xff0c;数据量少&#xff0c;开发人员开发功能时更重视功能上的实现&#xff0c;随着生产数据的增长&#xff0c;很多SQL语句开始暴露出性能问题&#xff0c;对生产的影响也越来越大&#xff0c;有时可能这些有问题的SQL就是整个系统性能的瓶颈。 SQL优化…

多功能音乐沙漏的设计与实现

【摘要】随着当今社会快节奏生活的发展&#xff0c;当代大学生越来忽视时间管理的重要性&#xff0c;在原本计划只看几个视频只玩几个游戏的碎片化娱乐中耗费了大量的时光&#xff0c;对于自己原本的学习生活产生了巨大的影响。为更加有效的反映时间的流逝&#xff0c;特设计该…

智慧公厕客流统计,是通过什么原理实现的?

在这个信息爆炸的时代&#xff0c;科技已经深刻地渗透到我们生活的方方面面&#xff0c;就连那些看似与现代社会脱节的公厕&#xff0c;也迎来了智慧时代的冲击。智慧公厕客流统计系统的崭新面貌&#xff0c;不仅实现了对卫生间使用情况的精准监测&#xff0c;更为城市管理者提…

第十七章 解读PyTorch断点训练(工具)

主要有以下几方面的内容&#xff1a; 对于多步长训练需要保存lr_schedule初始化随机数种子保存每一代最好的结果 简单详细介绍 最近在尝试用CIFAR10训练分类问题的时候&#xff0c;由于数据集体量比较大&#xff0c;训练的过程中时间比较长&#xff0c;有时候想给停下来&…

Gitee上传代码教程

1. 本地安装git 官网下载太慢&#xff0c;我们也可以使用淘宝镜像下载&#xff1a;CNPM Binaries Mirror 安装成功以后电脑会有Git Bush标识&#xff0c;空白处右键也可查看。 2. 注册gitee账号&#xff08;略&#xff09; 3. 创建远程仓库 4. 上传代码 4.1 在项目文件目录…

go当中的channel 无缓冲channel和缓冲channel的适用场景、结合select的使用

Channel Go channel就像Go并发模型中的“胶水”&#xff0c;它将诸多并发执行单元连接起来&#xff0c;或者正是因为有channel的存在&#xff0c;Go并发模型才能迸发出强大的表达能力。 无缓冲channel 无缓冲channel兼具通信和同步特性&#xff0c;在并发程序中应用颇为广泛。…

坚鹏:贵州银行西南财经大学零售业务数字化转型与场景营销策略

中国银保监会2022年1月正式发布了中国银保监会发布《关于银行业保险业数字化转型的指导意见》&#xff0c;这标准着中国银行业从局部的数字化转型向全面的数字化转型转变&#xff0c;进一步加速了银行数字化转型高潮的到来。 《关于银行业保险业数字化转型的指导意见》提出明确…

【教学类-06-12】20231126 (二)三位数 如何让加减乘除题目从小到大排序(以0-110之间加法为例,做正序排列用)

结果展示 背景需求&#xff1a; 二位数&#xff1a;去0 三位数&#xff08;需要排除很多0&#xff09; 解决思路 一、把数字改成三位数 二、对数组内的题目&#xff0c;8种可能性进行去“0”处理 1、十位数&#xff08;去百位数0&#xff09;十位数&#xff08;去百位数0&am…

淘宝商品详情数据API接口php java python

在当今竞争激烈的电子商务环境中&#xff0c;如何提高用户体验、提升运营效率并保障交易安全性是每个电商平台都需要关注的问题。淘宝作为中国最大的综合性电商平台&#xff0c;一直在不断创新和完善自身的服务体系。其中&#xff0c;淘宝商品详情API接口在跨境系统中发挥着越来…

【C/PTA】指针专项练习(一)

本文结合PTA专项练习带领读者掌握指针&#xff0c;刷题为主注释为辅&#xff0c;在代码中理解思路&#xff0c;其它不做过多叙述。 目录 6-1 删除字符串中数字字符6-2 找最大值及其下标6-3 求两数平方根之和6-4 求一组数中的最大值、最小值和平均值6-5 两个4位正整数的后两位互…

HuggingFace学习笔记--Tokenizer的使用

1--AutoTokenizer的使用 官方文档 AutoTokenizer() 常用于分词&#xff0c;其可调用现成的模型来对输入句子进行分词。 1-1--简单Demo 测试代码&#xff1a; # 分词器测试Demo from transformers import AutoTokenizerif __name__ "__main__":checkpoint "…

数据增强让模型更健壮

在做一些图像分类训练任务时,我们经常会遇到一个很尴尬的情况,那就是: 明明训练数据集中有很多可爱猫咪的照片,但是当我们给训练好的模型输入一张戴着头盔的猫咪进行测试时,模型就不认识了,或者说识别精度很低。 很明显,模型的泛化能力太差,难道戴着头盔的猫咪就不是猫…

线性分类器--数据处理

数据集划分 通常按照 70%&#xff0c;20% &#xff0c;10% 来分数据集 数据处理 斯坦福的线性分类器体验 http://vision.stanford.edu/teaching/cs231n-demos/linear-classify/

找工作面试技巧

问题描述&#xff1a;找工作时&#xff0c;不知道如何回答问题怎么办。 问题解决&#xff1a;可以尝试使用STAT原则来回答问题。具体如下。 "STAR" 原则是一种常用于回答面试问题的方法&#xff0c;特别是在描述个人经验、解决问题或展示技能和能力时。"STAR&q…

【解决视觉引导多个位置需要标定多个位置的问题】

** 以下只针对2D定位&#xff0c;就是只有X、Y、Rz三个自由度的情况。** 假设一种情况&#xff0c;当视觉给机器人做引导任务时&#xff0c;零件有多个&#xff0c;分布在料框里&#xff0c;视觉需要走多个位置去拍&#xff0c;那么只需要对第一个位置确定拍照位&#xff0c;确…

QContextMenuEvent 是 Qt 框架中的一个类,用于表示上下文菜单事件

QContextMenuEvent 是 Qt 框架中的一个类&#xff0c;用于表示上下文菜单事件。 上下文菜单事件&#xff08;Context Menu Event&#xff09;在用户右击部件时触发&#xff0c;通常用于显示上下文菜单。这些菜单可以包含与所选部件相关的操作和选项。 QContextMenuEvent 类提…

C语言重点编程题——1-10

目录 1.编一个程序,输入10个整数,统计并输出其中正数、负数和零的个数。 2.编程序,按下列公式计算e的值(精度为1e-6)e=1+1/1!+1/2!+1/3!.......1/n! 3.编程,输入n个整数,求这n个数的偶数平均值,并输出。 4.若一个3位整数的各位数字的立方和等于这个整数,则称之为“水…

美SEC与贝莱德,对比特币现货ETF申购方式产生分歧!

比特币现货ETF的通过时间是市场投资者密切关注的议题。虽然SEC最近推迟了Hashdex、富兰克林邓普顿&#xff08;Franklin Templeton&#xff09;和GlobalX申请的决议时间&#xff0c;但彭博ETF分析师James Seyffart对明年一月通过的机率持乐观态度&#xff0c;认为其通过的机会能…

Java - Stream Filter 多条件筛选过滤

Java Stream流中Filter用于通过设置的条件过滤出元素 &#xff0c;示例如下&#xff1a; List strings Arrays.asList(“abc”, “”, “bc”, “efg”, “abcd”,"", “jkl”);List filtered strings.stream().filter(string -> !string.isEmpty()).collect(C…

Java编译过程中的JVM

流程 源代码编写&#xff1a; 首先&#xff0c;开发者使用Java编程语言编写源代码。这些源代码通常保存在扩展名为.java的文件中。 编译源代码&#xff1a; 使用Java编译器&#xff08;例如javac&#xff09;&#xff0c;这些.java文件被编译成Java字节码。字节码是一种中间形…