Day4 商品管理

news2024/12/25 0:58:47

Day4 商品管理

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

学习方法:

1 github源码 + 文档 + 官网

2 内容复现 ,实际操作

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

编写品牌服务

/**
 * Brand service 实现common中的类
 *
 * @author bootsCoder
 * @date created on 2024/4/15
 */
@DubboService
@Transactional
public class BrandServiceImpl implements BrandService {
    @Autowired
    private BrandMapper brandMapper;

    /**
     * 根据id查询品牌
     * @param id
     * @return
     */
    @Override
    public 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);
    }

    @Override
    public List<Brand> findAll() {
        return brandMapper.selectList(null);
    }

    @Override
    public void add(Brand brand) {
        brandMapper.insert(brand);
    }

    @Override
    public void update(Brand brand) {
        brandMapper.updateById(brand);
    }

    @Override
    public void delete(Long id) {
        brandMapper.deleteById(id);
    }

    @Override
    public 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 {
    @Autowired
    private ProductTypeMapper productTypeMapper;
    @Override
    public void add(ProductType productType) {
        // 根据父类型id查询父类型
        ProductType productTypeParent = productTypeMapper.selectById(productType.getParentId());
        // 根据父类型的级别,来设置当前类型的级别
        if (productTypeParent == null){ // 如果没有父类型,则为1级类型
            productType.setLevel(1);
        } else if (productTypeParent.getLevel() < 3) { // 如果父类型级<3 则级别为父级别+1
            productType.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 mapper
        PUBLIC "-//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">
        SELECT
            boots_specification.id AS bid,
            boots_specification.specName,
            boots_specification.productTypeId,
            boots_specification_option.id AS oid,
            boots_specification_option.optionName,
            boots_specification_option.specId
        FROM
            boots_specification
                LEFT JOIN boots_specification_option
                          ON boots_specification.id = boots_specification_option.specId
        WHERE
            boots_specification.id = #{id}
    </select>

    <select id="findByProductTypeId" parameterType="long" resultMap="specificationMapper">
        SELECT
            boots_specification.id AS bid,
            boots_specification.specName,
            boots_specification.productTypeId,
            boots_specification_option.id AS oid,
            boots_specification_option.optionName,
            boots_specification_option.specId
        FROM
            boots_specification
                LEFT JOIN boots_specification_option
                          ON boots_specification.id = boots_specification_option.specId
        WHERE
            boots_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: DISABLE
   check-serializable: false
  protocol:
   name: dubbo # 通讯协议
   port: -1 # 端口号,-1表示自动扫描可用端口。
  registry:
   address: nacos://192.168.66.100:8848 # 注册中心


fdfs:
  so-timeout: 3000
  connect-timeout: 6000
  tracker-list: # TrackerList路径
   - 192.168.66.100:22122
  fileUrl: http://192.168.66.100:81 # 自定义配置,文件访问路径

文件服务实现

安装+配置+启动 fastdfs 和nginx

@DubboService
public class FileServiceImpl implements FileService {
  @Autowired
  private FastFileStorageClient fastFileStorageClient;
  @Value("${fdfs.fileUrl}")
  private String fileUrl; // Nginx访问FastDFS中文件的路径


  @Override
  public 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);
     }
   }


  @Override
  public void delete(String filePath) {
    fastFileStorageClient.deleteFile(filePath);
   }
}

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

—>对象没有进行序列化

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

–> 需要进行byte数组转换

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

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

image-20240418210824087

image-20240418211544802

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

测试商品增删查改功能

 @Override
    public void add(Goods goods) {
        // 插入商品数据
        goodsMapper.insert(goods);
        // 插入图片数据
        Long goodsId = goods.getId(); // 获取商品主键
        List<GoodsImage> images = goods.getImages(); // 商品图片集合
        for (GoodsImage image : images) {
            image.setGoodsId(goodsId); // 给图片设置商品id
            goodsImageMapper.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">
    SELECT
        boots_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 optionName
    FROM
        boots_goods
    LEFT JOIN boots_goods_image ON boots_goods.id = boots_goods_image.goodsId
    LEFT JOIN boots_goods_specification_option ON boots_goods.id = boots_goods_specification_option.gid
    LEFT JOIN boots_specification_option ON boots_goods_specification_option.optionId = boots_specification_option.id
    LEFT JOIN boots_specification ON boots_specification_option.specId = boots_specification.id
    WHERE
        boots_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://www.coloradmin.cn/o/1617323.html

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

相关文章

LangChain入门指南:构建高可复用、可扩展的LLM应用程序 PDF书籍分享

今天又来给大家推荐一本大模型方面的书籍<Langchain入门指南>这本书专门为那些对自然语言处理技术感兴趣的读者提供了系统的LLM应用开发指南。全书分为11章&#xff0c;从LLM基础知识开始&#xff0c;通过LangChain这个开源框架为读者解读整个LLM应用开发流程。 下载当前…

轻松记录收支明细,详细记录每一笔收支,通过借款日期快速查找借款信息

财务管理对于个人和企业来说都至关重要。一份清晰、详尽的收支明细记录&#xff0c;不仅能帮助我们了解资金流向&#xff0c;还能在需要时提供有力的证据。因此&#xff0c;高效记录收支明细并轻松掌握财务状况成为了每个人的必备技能 第一步进入晨曦记账本主页面&#xff0c;…

ros2_control【B站WMGIII教学学习记录】1

资源 https://www.bilibili.com/video/BV1ku411G7UR? 学习过程中存在bug&#xff0c;记录一下 1 Q:"package ‘joint_state_publisher_gui’ not found, searching: [/home A: sudo apt install ros-humble-joint-state-publisher2 https://fishros.org.cn/forum/to…

抢先看!LEADTOOLS V23 全新版发布,预览全新产品线布局!

LEADTOOLS (Lead Technology)由Moe Daher and Rich Little创建于1990年&#xff0c;其总部设在北卡罗来纳州夏洛特。LEAD的建立是为了使Daher先生在数码图象与压缩技术领域的发明面向市场。在过去超过30年的发展历程中&#xff0c;LEAD以其在全世界主要国家中占有的市场领导地位…

SpringCloud引入SpringBoot Admin

Spring Boot Admin可以监控和管理Spring Boot&#xff0c;能够将 Actuator 中的信息进行界面化的展示&#xff0c;也可以监控所有 Spring Boot 应用的健康状况&#xff0c;提供警报功能。 1. 创建SpringBoot工程 2. 引入相关依赖 <dependency><groupId>com.alib…

基于ontape的备份与恢复实验

通过本文的备份恢复实验&#xff0c;我们可以深入了解ontape的使用方法和原理&#xff0c;包括如何进行完整备份、增量备份以及如何利用备份文件进行数据恢复。 1. 配置onconfig参数 通过修改onconfig参数文件&#xff0c;或使用onmode -wf命令&#xff0c;设置备份默认使用的…

电商巨头亚马逊公布新算法!或将颠覆跨境选品风向…

亚马逊每一次算法的变动&#xff0c;都会牵扯到无数卖家的利益。电商巨头亚马逊发布了一则报告&#xff0c;正式公布了一个名为“COSMO”的新算法。该算法全称为“亚马逊大型电商常识知识生成与服务系统”&#xff0c;顾名思义&#xff0c;就是利用大量语言模型训练机器&#x…

DSP系统的设计过程与选型

DSP的设计步骤分几个阶段&#xff0c;应用系统的设计过程如图所示。 技术指标的确定 器件的选型原则 其他因素的考虑

谈谈mysql中的各个关键字

1.为什么学习mysql mysql是当今最主流且开放源码的关系型数据库&#xff0c;开发者为瑞典 MySQL AB 公司。目前 MySQL 被广泛地应用在 Internet 上的中小型网站中。由于其体积小、速度快、总体拥有成本低&#xff0c;尤其是开放源码这一特点&#xff0c;许多中小型网站为了降低…

第G8周:ACGAN任务

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 | 接辅导、项目定制&#x1f680; 文章来源&#xff1a;K同学的学习圈子 参考论文 这周主要任务就是根据之前GAN&#xff0c;CGAN&#xff0c;SGAN网络架构搭建…

OpenStack云计算(十一)——OpenStack网络管理,验证OpenStack网络资源模型,验证来巩固和加深对OpenStack网络资源模型的理解

项目实训一 【实训题目】 验证OpenStack网络资源模型 【实训目的】 通过验证来巩固和加深对OpenStack网络资源模型的理解。 【实训准备】 &#xff08;1&#xff09;复习Neutron网络资源模型。 &#xff08;2&#xff09;重点理解网络、子网、端口和路由器的概念。 【实…

使用LLM-API开发应用-DataWhale笔记

调用API 先使用一个例子 from openai import OpenAI ​ client OpenAI(# This is the default and can be omittedapi_keyos.environ.get("OPENAI_API_KEY"), //这个在环境env中 ) ​ completion client.chat.completions.create(# 调用模型&#xff1a;ChatGPT-…

科研基础与工具(论文写作)

免责申明&#xff1a; 本文内容只是学习笔记&#xff0c;不代表个人观点&#xff0c;希望各位看官自行甄别 参考文献 科研基础与工具&#xff08;YouTube&#xff09; 学术写作句型 Academic Phrase bank 曼彻斯特大学维护的一个网站 写论文的时候&#xff0c;不不知道怎么…

vue快速入门(四十一)组件通信-依赖注入

注释很详细&#xff0c;直接上代码 上一篇 新增内容 祖先组件向下传值子代组件接受数据 源码 App.vue <template><div id"app"><sonComponent></sonComponent></div> </template> <script> import sonComponent from &qu…

广东海洋大学成功部署(泰迪智能科技)大数据人工智能实验室建设

广东海洋大学简称广东海大&#xff0c;坐落于广东省湛江市&#xff0c;是国家海洋局与广东省人民政府共建的省属重点建设大学、广东省高水平大学重点学科建设高校、粤港澳高校联盟成员 &#xff0c;入选卓越农林人才教育培养计划&#xff0c;是教育部本科教学水平评估优秀院校。…

隋总分享的Temu蓝海项目究竟能不能做?

在当前的互联网经济大潮中&#xff0c;跨境电商作为一个新兴的商业模式&#xff0c;吸引了众多创业者和投资者的目光。其中&#xff0c;Temu作为拼多多旗下的跨境电商平台&#xff0c;凭借其独特的模式和强大的背景&#xff0c;成为了不少人心中的蓝海项目。近日&#xff0c;网…

java中线程的生命周期和线程安全

目录 生命周期 线程安全 生命周期 在Java中&#xff0c;线程的生命周期可以分为以下几个状态&#xff1a; 新建状态&#xff08;New&#xff09;&#xff1a; 当线程对象被创建后&#xff0c;它就处于新建状态。此时线程对象已经在内存中了&#xff0c;但是还没有开始执行。…

提升效率与质量:钣金加工行业设备数据采集的重要性

钣金加工作为制造业的重要一环&#xff0c;在现代工业中扮演着举足轻重的角色。随着市场竞争的日益激烈&#xff0c;钣金加工企业必须不断提升生产效率和产品质量&#xff0c;以应对市场的挑战。在这一背景下&#xff0c;设备数据采集变得尤为重要&#xff0c;因为它可以帮助企…

Dapp智能合约开发搭建

随着区块链技术的飞速发展&#xff0c;去中心化应用&#xff08;Dapp&#xff09;逐渐崭露头角&#xff0c;成为金融科技领域的一股新势力。而在Dapp中&#xff0c;智能合约发挥着不可或缺的作用。本文将从专业角度深入探讨Dapp智能合约的概念、优势、挑战以及未来发展趋势&…

Service: Amazon S3; Status Code: 403; Error Code: AccessDenied

1、使用minio报错 Access Denied. (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: 17C8C89ED481E74E; S3 Extended Request ID: dd9025bab4ad464b049177c95eb6ebf374d3b3fd1af9251148b658df7ac2e3e8; Proxy: null) 2、将Access Policy值改为…