Day4 商品管理

Day4 商品管理

这里会总结构建项目过程中遇到的问题,以及一些个人思考!!

学习方法:

1 github源码 + 文档 + 官网

2 内容复现 ,实际操作

项目源码同步更新到github 欢迎大家star~ 后期会更新并上传前端项目

编写品牌服务

/*** Brand service 实现common中的类** @author bootsCoder* @date created on 2024/4/15*/
@DubboService
@Transactional
public class BrandServiceImpl implements BrandService {@Autowiredprivate BrandMapper brandMapper;/*** 根据id查询品牌* @param id* @return*/@Overridepublic Brand findById(Long id) {if (id == 0){int i = 1/0; // 模拟系统异常}else if(id == -1){throw new MyException(ResultCode.PARAMETER_ERROR); // 模拟业务异常}return brandMapper.selectById(id);}@Overridepublic List<Brand> findAll() {return brandMapper.selectList(null);}@Overridepublic void add(Brand brand) {brandMapper.insert(brand);}@Overridepublic void update(Brand brand) {brandMapper.updateById(brand);}@Overridepublic void delete(Long id) {brandMapper.deleteById(id);}@Overridepublic Page<Brand> search(Brand brand, int page, int size) {QueryWrapper<Brand> queryWrapper = new QueryWrapper();// 判断品牌名是否为空if (brand != null && StringUtils.hasText(brand.getName())){queryWrapper.like("name",brand.getName());}Page page1 = brandMapper.selectPage(new Page(page, size), queryWrapper);return page1;}
}

Brand 完成

商品类型


@DubboService
@Transactional
public class ProductTypeServiceImpl implements ProductTypeService {@Autowiredprivate ProductTypeMapper productTypeMapper;@Overridepublic void add(ProductType productType) {// 根据父类型id查询父类型ProductType productTypeParent = productTypeMapper.selectById(productType.getParentId());// 根据父类型的级别,来设置当前类型的级别if (productTypeParent == null){ // 如果没有父类型,则为1级类型productType.setLevel(1);} else if (productTypeParent.getLevel() < 3) { // 如果父类型级<3 则级别为父级别+1productType.setLevel(productTypeParent.getLevel() + 1);} else if (productTypeParent.getLevel() == 3){ // 如果父类型级=3 则不能添加子级别throw new MyException(ResultCode.INSERT_PRODUCT_TYPE_ERROR);}productTypeMapper.insert(productType);}
}
image-20240418202927525

image-20240418203000901

商品规格项

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bootscoder.shopping_goods_service.mapper.SpecificationMapper"><resultMap id="specificationMapper" type="com.bootscoder.shopping_common.pojo.Specification"><id property="id" column="bid"></id><result property="specName" column="specName"></result><result property="productTypeId" column="productTypeId"></result><collection property="specificationOptions" column="specId" ofType="com.bootscoder.shopping_common.pojo.SpecificationOption"><id property="id" column="oid"></id><result property="optionName" column="optionName"></result><result property="specId" column="specId"></result></collection></resultMap><select id="findById" parameterType="long" resultMap="specificationMapper">SELECTboots_specification.id AS bid,boots_specification.specName,boots_specification.productTypeId,boots_specification_option.id AS oid,boots_specification_option.optionName,boots_specification_option.specIdFROMboots_specificationLEFT JOIN boots_specification_optionON boots_specification.id = boots_specification_option.specIdWHEREboots_specification.id = #{id}</select><select id="findByProductTypeId" parameterType="long" resultMap="specificationMapper">SELECTboots_specification.id AS bid,boots_specification.specName,boots_specification.productTypeId,boots_specification_option.id AS oid,boots_specification_option.optionName,boots_specification_option.specIdFROMboots_specificationLEFT JOIN boots_specification_optionON boots_specification.id = boots_specification_option.specIdWHEREboots_specification.productTypeId = #{productTypeId}</select>
</mapper>

image-20240418203835521

文件服务模块

搜索成功

分页查询成功

# 端口号
server:port: 9003# 日志格式
logging:pattern:console: '%d{HH:mm:ss.SSS} %clr(%-5level) ---  [%-15thread] %cyan(%-50logger{50}):%msg%n'spring:application:name: shopping_file_service #服务名cloud:nacos:discovery:server-addr: 192.168.66.100:8848 # 注册中心地址dubbo:application:name: shopping_file_service #服务名serialize-check-status: DISABLEcheck-serializable: falseprotocol:name: dubbo # 通讯协议port: -1 # 端口号,-1表示自动扫描可用端口。registry:address: nacos://192.168.66.100:8848 # 注册中心fdfs:so-timeout: 3000connect-timeout: 6000tracker-list: # TrackerList路径- 192.168.66.100:22122fileUrl: http://192.168.66.100:81 # 自定义配置,文件访问路径

文件服务实现

安装+配置+启动 fastdfs 和nginx

@DubboService
public class FileServiceImpl implements FileService {@Autowiredprivate FastFileStorageClient fastFileStorageClient;@Value("${fdfs.fileUrl}")private String fileUrl; // Nginx访问FastDFS中文件的路径@Overridepublic String uploadImage(byte[] fileBytes, String fileName) {if (fileBytes.length != 0) {try {// 1.将文件的字节数组转为输入流ByteArrayInputStream inputStream = new ByteArrayInputStream(fileBytes);// 2.获取文件的后缀名String fileSuffix = fileName.substring(fileName.lastIndexOf(".") + 1);// 3.上传文件StorePath storePath = fastFileStorageClient.uploadFile(inputStream, inputStream.available(), fileSuffix, null);// 4.返回图片路径String imageUrl = fileUrl + "/"+storePath.getFullPath();return imageUrl;}catch (Exception e){throw new BusException(CodeEnum.UPLOAD_FILE_ERROR);}} else {throw new BusException(CodeEnum.UPLOAD_FILE_ERROR);}}@Overridepublic void delete(String filePath) {fastFileStorageClient.deleteFile(filePath);}
}

上传文件时使用springMVC 将文件转换为multipartFile

—>对象没有进行序列化

消费者和生产者使用dubbo进行服务调用;数据需要实现接口序列化

–> 需要进行byte数组转换

删除的时候直接根据文件路径进行删除

上传的图片存到了服务器中
image-20240418210759579

image-20240418210824087

image-20240418211544802

在考虑后期是不是可以把这个图床配置一下改到我的oss 阿里云的图床上面;或者把服务器的配置改到其他的服务器上面是不是也可行(如果没有端口限制就好了)

测试商品增删查改功能

 @Overridepublic void add(Goods goods) {// 插入商品数据goodsMapper.insert(goods);// 插入图片数据Long goodsId = goods.getId(); // 获取商品主键List<GoodsImage> images = goods.getImages(); // 商品图片集合for (GoodsImage image : images) {image.setGoodsId(goodsId); // 给图片设置商品idgoodsImageMapper.insert(image); // 插入图片}// 插入商品_规格项数据// 1.获取规格List<Specification> specifications = goods.getSpecifications();// 2.获取规格项List<SpecificationOption> options = new ArrayList();// 3.1 遍历规格,获取规格中的所有规格项for (Specification specification : specifications) {options.addAll(specification.getSpecificationOptions());}// 3.2 遍历规格项,插入商品_规格项数据for (SpecificationOption option : options) {goodsMapper.addGoodsSpecificationOption(goodsId,option.getId());}}

关于逻辑:

这里注意一下商品的信息一般不能删除,涉及到用户的订单,将无法查找到对应的商品信息;

添加一个逻辑删除的功能即可

image-20240418212634076

存在的bug:

  1. 无法查看商品
  2. 无法在商品介绍中添加图片
  3. 注释ES后无法查看商品最后一张商品的信息;但是可以查看第一张图片的商品信息;删除本地记录后 等待30s 第一张图片也无法访问; 刷新后又可以进行访问

猜测:

因为新插入的图片没来得及和中间表关联

image-20240418214430886

image-20240418214519089

image-20240418214642662

观察后发现后端数据库中出现了奇怪的拼接

image-20240418235054619image-20240419020718124

检测到问题;代码中的联表方法必须有规格才能查看

<select id="findById" parameterType="long" resultMap="goodsMapper">SELECTboots_goods.id AS bid,boots_goods.goodsName AS goodsName,boots_goods.caption AS caption,boots_goods.price AS price,boots_goods.headerPic AS headerPic,boots_goods.introduction AS introduction,boots_goods.isMarketable AS isMarketable,boots_goods.brandId AS brandId,boots_goods.productType1Id AS productType1Id,boots_goods.productType2Id AS productType2Id,boots_goods.productType3Id AS productType3Id,boots_goods_image.id AS imageId,boots_goods_image.imageTitle AS imageTitle,boots_goods_image.imageUrl AS imageUrl,boots_specification.id AS specificationId,boots_specification.specName AS specName,boots_specification.productTypeId AS productTypeId,boots_specification_option.id AS optionId,boots_specification_option.optionName AS optionNameFROMboots_goodsLEFT JOIN boots_goods_image ON boots_goods.id = boots_goods_image.goodsIdLEFT JOIN boots_goods_specification_option ON boots_goods.id = boots_goods_specification_option.gidLEFT JOIN boots_specification_option ON boots_goods_specification_option.optionId = boots_specification_option.idLEFT JOIN boots_specification ON boots_specification_option.specId = boots_specification.idWHEREboots_goods.id = #{gid}
</select>

image-20240419022649213

从inner修改到left后发现,可以正常查询

慢sql 多表联查问题(乌龙)

出现的新问题,出现了慢sql语句; --> 点击一次查看后很难快速点击下一次查看

Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@12e56665]
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2bef026]
Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@12e56665]
Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2bef026]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@12e56665]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@12e56665]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2bef026]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2bef026]

这些日志信息来自使用 MyBatis 框架的 Java 应用程序,在事务处理过程中记录了各个步骤。下面是每条日志的详细解释:

  1. Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@12e56665][org.apache.ibatis.session.defaults.DefaultSqlSession@2bef026]: 这表示两个不同的 SqlSession 实例正在从事务管理中释放。这通常发生在事务即将完成时,MyBatis 准备将这些会话返回到会话池中。
  2. Transaction synchronization committing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@12e56665][org.apache.ibatis.session.defaults.DefaultSqlSession@2bef026]: 这表示两个 SqlSession 实例正在提交它们的事务。在这一步,所有的更改(如果有的话)被保存到数据库中。
  3. Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@12e56665][org.apache.ibatis.session.defaults.DefaultSqlSession@2bef026]: 这说明这两个 SqlSession 实例正在从事务同步管理中注销。这通常发生在事务提交或回滚之后。
  4. Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@12e56665][org.apache.ibatis.session.defaults.DefaultSqlSession@2bef026]: 这表示这两个 SqlSession 实例正在关闭。关闭操作确保所有的资源都被适当释放,连接被归还到数据库连接池。

提问:如果只是简单的慢sql的话,那么为什么长时间没有反应呢?image-20240419023337509

经过postman和浏览器访问后,重复点击多次仍然有响应,考虑是前端的问题

  1. 缓存问题:可能浏览器或前端应用缓存了第一次请求的结果。您可以尝试禁用缓存或在请求时添加时间戳来确保每次请求都是唯一的。
  2. 后端接口状态问题:如果后端接口在处理完第一次请求后有状态变化或未正确关闭资源(例如数据库连接),可能导致后续请求无法处理。
  • Phantom Reads:虽然REPEATABLE-READ保证了不会出现不一致的重复读,但它不能完全防止幻读。幻读是指在一个事务内读取某范围的记录时,另一个事务插入了新记录,再次查询时看到了新的、之前不存在的记录。在REPEATABLE-READ下,通过间隙锁可以部分避免幻读,但在某些情况下仍然可能发生。

md 我真出现了 之前的图片出现在不同的mysql 的不同的数据中image-20240419032418665

目前暂时未检查出mysql数据库的死锁

邪门了 就只有这一个玩意不能多次查看, 而且是一点完别的本来嫩点的也不能点了

image-20240419031705750

image-20240419032127549

卧槽找到了 isMarkatebal 改变;上下架不改变其值;无效;;;还是不行

修复了!卧槽 因为之前的规格里面没选机身内存image-20240419034353337

image-20240419035010725

image-20240419035105025

image-20240419035135926

image-20240419035223273

前端的查询逻辑可能有点问题;

image-20240419040320145

我还是觉得很神奇; 难道是点击事件认为这件事还没有做完 所以没有cancel?

秒杀商品成功

这里多bb一嘴哈, 因为昨天晚上电脑开虚拟机卡爆了,强制重启,导致文件有损坏;没想到typora 给我留了一个文件夹进行历史恢复,真的cool;详情见偏好设置,未保存文档;(好像还有一个是历史文档的东东, 之前那个旧版本没有, 直接找楠妮儿 要到了她的正版序列号,nice!然后重新配置了一下图床)

image-20240422133235253

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

在线预约订房酒店小程序源码系统 带完整的安装代码包以及=安装部署教程

传统的酒店预订方式往往依赖于电话、邮件或者到店咨询&#xff0c;这种方式不仅效率低下&#xff0c;而且容易造成信息不准确、沟通不畅等问题。随着智能手机的普及和移动互联网的发展&#xff0c;用户对于随时随地、方便快捷地进行酒店预订的需求日益增强。小编给大家分享一款…

[MySQL]运算符

1. 算术运算符 (1). 算术运算符 : , -, *, / 或 DIV, % 或MOD. (2). 例 : (3). 注 : DUAL是伪表.可以看到4/2结果为小数&#xff0c;并不会截断小数部分.(可能与其他语言不同&#xff0c;比如java中&#xff0c;两个操作数如果是整数&#xff0c;则计算得到的也是整数&…

羊大师:夏季羊奶的好处有哪些?

夏季羊奶的好处主要包括以下几点 1.增强免疫力&#xff1a;羊奶中的钙元素丰富&#xff0c;能有效为身体补充营养物质&#xff0c;增强自身的免疫能力。羊奶还富含上皮细胞生长因子&#xff08;EGF&#xff09;&#xff0c;对人体鼻腔、咽喉、血管、肠胃等黏膜有良好的修复作用…

Qt 跨平台开发的一丢丢总结

Qt 跨平台开发 文章目录 Qt 跨平台开发摘要第一 \ & /第二 神奇{不能换行显示第三 预处理宏 关键字&#xff1a; Qt、 win、 linux、 lib、 MSVC 摘要 最近一直在琢磨Qt跨平台开发的问题&#xff0c;缘由有以下几个&#xff0c; 首先第一个&#xff0c;我们目前开发…

几种比Serv-u更好满足企业的替代工具方案

很多目前企业面临的挑战是如何在保障数据安全的同时&#xff0c;提高文件传输的效率。传统的FTP服务器&#xff0c;如Serv-U&#xff0c;虽然长期服务于文件共享与传输&#xff0c;但在新兴需求面前显得力不从心。 于是企业开始寻求更先进的解决方案以应对跨地域、大容量的文件…

Vue 3中的ref和toRefs:响应式状态管理利器

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【图说】VMware Ubuntu22.04 详细安装教程

前言 无论是从事 Linux 开发工作&#xff0c;还是希望电脑运行双系统&#xff0c;VMware 虚拟机都是我们日常工作不可或缺的工具。本章将会重点介绍 VMware 安装流程&#xff0c;以及在 VMware 上如何运行、使用 Ubuntu22.04 系统。 一、VMware 下载安装 1.1 VMware 官网下载…

【Hello算法】 > 第 3 关 >栈与队列

数据结构 之 数组与链表 1 栈 / 栈的常见操作、实现、应用2 队列 /队列的常见操作、实现、应用3 双向队列4 Tips ———————————————————————————————————————————————————————————- ————————————————…

鼠标坐标传感器FCT3065

参考链接 如何优雅的DIY鼠标&#xff1f; | 技术文章 | 汇顶科技开发者社区 (goodix.com)https://developers.goodix.com/zh/bbs/blog_detail/bebdd04ccdfc4f7682ab27a8e77a14ad GitHub - VineetSukhthanker/FCT3065-XY_MouseSensor: Interface FCT3065-XY optical mouse sen…

面试算法准备:动态规划

这里写自定义目录标题 1 理论2 例题2.1 斐波那契数列&#xff08;什么是重叠子问题&#xff09;2.1.1 带备忘录的递归解法 2.2 零钱兑换&#xff08;讲解最优子结构&#xff09;2.3 最长递增子序列&#xff08;讲解如何求解状态转移方程&#xff09;2.4 俄罗斯套娃信封问题&…

Vue3、 Vue2 Diff算法比较

Vue2 Diff算法 源码位置:src/core/vdom/patch.ts 源码所在函数:updateChildren() 源码讲解: 有新旧两个节点数组:oldCh和newCh; 有下面几个变量: oldStartIdx 初始值=0 oldStartVnode 初始值=oldCh[0] oldEndIdx 初始值=oldCh.length - 1 oldEndVnode 初始值=oldCh[ol…

鸿蒙 harmonyos 线程 并发 总结 async promise Taskpool woker(三)多线程并发 Worker

Worker Worker是与主线程并行的独立线程。创建Worker的线程称之为宿主线程&#xff0c;Worker自身的线程称之为Worker线程。创建Worker传入的url文件在Worker线程中执行&#xff0c;可以处理耗时操作但不可以直接操作UI。 Worker主要作用是为应用程序提供一个多线程的运行环境…

CTFshow-PWN-栈溢出(pwn36)

存在后门函数&#xff0c;如何利用&#xff1f; 好好好&#xff0c;终于到了这种有后门函数的了 checksec 检查一下&#xff1a; 32 位程序&#xff0c;RELRO 保护部分开启 RWX: Has RWX segments 存在可读可写可执行的段 使用 ida32 看 main 函数 跟进 ctfshow 函数…

Scala 04 —— Scala Puzzle 拓展

Scala 04 —— Scala Puzzle 拓展 文章目录 Scala 04 —— Scala Puzzle 拓展一、占位符二、模式匹配的变量和常量模式三、继承 成员声明的位置结果初始化顺序分析BMember 类BConstructor 类 四、缺省初始值与重载五、Scala的集合操作和集合类型保持一致性第一部分代码解释第二…

L3-1 夺宝大赛-2024天梯赛(内存超限解决方法)

题目 夺宝大赛的地图是一个由 nm 个方格子组成的长方形&#xff0c;主办方在地图上标明了所有障碍、以及大本营宝藏的位置。参赛的队伍一开始被随机投放在地图的各个方格里&#xff0c;同时开始向大本营进发。所有参赛队从一个方格移动到另一个无障碍的相邻方格&#xff08;“…

聊聊如何通过arthas-tunnel-server来远程管理所有需要arthas监控的应用

前言 Arthas 是一款线上监控诊断产品&#xff0c;通过全局视角实时查看应用 load、内存、gc、线程的状态信息&#xff0c;并能在不修改应用代码的情况下&#xff0c;对业务问题进行诊断&#xff0c;包括查看方法调用的出入参、异常&#xff0c;监测方法执行耗时&#xff0c;类…

Redis入门到通关之Redis实现Session共享

文章目录 ☃️前期概要☃️基于Session实现登录方案☃️现有方案存在的问题☃️Redis代替Session的业务流程❄️❄️设计key的结构❄️❄️设计key的具体细节❄️❄️整体访问流程 欢迎来到 请回答1024 的博客 &#x1f353;&#x1f353;&#x1f353;欢迎来到 请回答1024的博…

redis原理篇(黑马程序员虎哥 )回忆笔记

原理&#xff0c;老师讲的真好。相见恨晚。 以下内容是按视频课程的章节安排&#xff0c;在我自己听完课之后&#xff0c;凭借记忆总结的。&#xff08;可能存在疏漏不足&#xff0c;后期补全和修正&#xff0c;同时也在这个过程巩固我自己的对于这个组件相关原理的学习&#x…

中国DIVI版,wordpress DIVI网站主题在国内的替代方案。

最受欢迎的WordPress主题之一是Divi。我们创建了这个全面的Divi主题评论&#xff0c;以帮助您更好地了解其优点和潜在缺点。 Divi主题是什么&#xff1f; Divi是一个流行的WordPress主题&#xff0c;提供了一个网站建设平台。它有一个可视化编辑器选项&#xff0c;为新手和专业…

手撕红黑树(map和set底层结构)(2)

[TOC]红黑树 一 红黑树概念 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff0c;可以是Red或Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制&#xff0c;红黑树确保没有一条路径会比其他路径长出俩倍&…