031 商品上架-增量同步和全量同步(cubemall-search模块)

文章目录

    • 增量同步
    • 全量同步
    • SpuInfoDao.xml
    • SpuInfo实体类
    • application.yml
    • pom.xml
    • SpuInfoController.java
    • SpuInfoDao.java
    • SpuInfoEntity.java
    • SpuInfoRepository.java
    • SpuInfoServiceImpl.java
    • CubemallSearchApplication.java

商品上架 商品索引全量同步

增量同步

1.功能分析

  1. 前端页面,点击"上架"链接,执行上架的动作
  2. 请求的url
    /product/spuinfo/{spuid}/up
    参数:
    spuid
    请求方法:
    post
    返回值:
    R(转换成json数据)
  3. product工程中
    controller:
    接收页面请求的参数
    调用service处理请求
    service:
    1接收controller传递过来的参数,spuId
    2根据spuId找到对应的商品修改商品状态
    修改tb_spuinfo表中的publish_status字段为1
    3需要把商品添加到索引库中,调用search工程的服务,实现ES索引库的添加
    4返回结果
  4. 服务之间调用使用OpenFeign技术
  5. Search工程中
    controller:
    接收请求的参数:spuId
    调用service商品添加到索引库
    Service:
    1.根据spuId查询对象的商品数据
    2.商品数据包含的字段 Entity中包含的字段
    3.使用ElasticSearchRepository对象将数据添加到索引库中
    4.返回结果

2.索引库中文档的结构
(1) 字段分析
tb_spu_info

  1. id
  2. spu_name
  3. spu_description
  4. category_id
  5. brand_id
  6. update_time

tb_category

  1. name

tb_brand

  1. name
  2. image

tb_spu_images

  1. img_url

tb_sku_info

  1. price 取最低价格

(2) SQL语句

全量同步

1.实现思路

  1. 把所有的商品数据查询出来
  2. 把商品数据导入到ES中
    2.dao层
    查询出所有上架状态的商品数据
        SELECT
            a.id,
            a.spu_name spuName,
            a.spu_description spuDescription,
            a.category_id categoryId,
            c.`name` categoryName,
            a.brand_id brandId,
            d.`name` brandName,
            d.image brandImage,
            a.update_time updateTime,
            b.img_url imgUrl,
            e.price
        FROM tb_spu_info a
                 left join (select * from tb_spu_images where default_img = 1) b on a.id=b.spu_id
                 left join tb_category c on a.category_id = c.id
                 left join tb_brand d on a.brand_id = d.id
                 left join (
            select spu_id, min(price) price from tb_sku_info GROUP BY spu_id
        ) e on a.id = e.spu_id
        WHERE a.publish_status=1

3.service层

  1. 把所有的商品数据查询出来
  2. 把商品数据导入到ES中

SpuInfoDao.xml

<?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.xd.cubemall.search.dao.SpuInfoDao">

	<!-- 可根据自己的需求,是否要使用 -->
    <resultMap type="com.xd.cubemall.search.entity.SpuInfoEntity" id="spuInfoMap">
        <result property="id" column="id"/>
        <result property="spuName" column="spu_name"/>
        <result property="spuDescription" column="spu_description"/>
        <result property="categoryId" column="category_id"/>
        <result property="brandId" column="brand_id"/>
        <result property="weight" column="weight"/>
        <result property="publishStatus" column="publish_status"/>
        <result property="createTime" column="create_time"/>
        <result property="updateTime" column="update_time"/>
    </resultMap>

    <select id="getSpuInfoById" parameterType="long" resultType="com.xd.cubemall.search.model.SpuInfo">
        SELECT
            a.id,
            a.spu_name spuName,
            a.spu_description spuDescription,
            a.category_id categoryId,
            c.`name` categoryName,
            a.brand_id brandId,
            d.`name` brandName,
            d.image brandImage,
            a.update_time updateTime,
            b.img_url imgUrl,
            e.price
        FROM tb_spu_info a
                 left join (select * from tb_spu_images where default_img = 1) b on a.id=b.spu_id
                 left join tb_category c on a.category_id = c.id
                 left join tb_brand d on a.brand_id = d.id
                 left join (
            select spu_id, min(price) price from tb_sku_info GROUP BY spu_id
        ) e on a.id = e.spu_id
        WHERE a.id=#{spuId}
    </select>

    <select id="getSpuInfoList" resultType="com.xd.cubemall.search.model.SpuInfo">
        SELECT
            a.id,
            a.spu_name spuName,
            a.spu_description spuDescription,
            a.category_id categoryId,
            c.`name` categoryName,
            a.brand_id brandId,
            d.`name` brandName,
            d.image brandImage,
            a.update_time updateTime,
            b.img_url imgUrl,
            e.price
        FROM tb_spu_info a
                 left join (select * from tb_spu_images where default_img = 1) b on a.id=b.spu_id
                 left join tb_category c on a.category_id = c.id
                 left join tb_brand d on a.brand_id = d.id
                 left join (
            select spu_id, min(price) price from tb_sku_info GROUP BY spu_id
        ) e on a.id = e.spu_id
        WHERE a.publish_status=1
    </select>


</mapper>


SpuInfo实体类

package com.xd.cubemall.search.model;

import lombok.Data;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.DateFormat;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import java.util.Date;

@Data
@Document(indexName = "goods_1", shards = 5, replicas = 1)
public class SpuInfo {
    @Id
    @Field(type = FieldType.Long)
    private Long id;
    @Field(type = FieldType.Text, store = true, analyzer = "ik_max_word")
    private String spuName;
    @Field(type = FieldType.Text, store = true, analyzer = "ik_max_word")
    private String spuDescription;
    @Field(type = FieldType.Long)
    private Long categoryId;
    @Field(type = FieldType.Keyword, store = true)
    private String categoryName;
    @Field(type = FieldType.Long)
    private Long brandId;
    @Field(type = FieldType.Keyword, store = true)
    private String brandName;
    @Field(type = FieldType.Keyword, store = true, index = false)
    private String brandImage;
    @Field(type = FieldType.Date, store = true, format = DateFormat.basic_date_time)
    private Date updateTime;
    @Field(type = FieldType.Keyword, store = true, index = false)
    private String imgUrl;
    @Field(type = FieldType.Double, store = true)
    private Double price;
}

application.yml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/cube_goods?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
    username: root
    password: root
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        ip: 127.0.0.1
  application:
    name: cubemall-search
  elasticsearch:
    rest:
      uris:
        - 1.1.1.1:9200
        - 2.2.2.2:9200
        - 3.3.3.3:9200
server:
  port: 8082
mybatis-plus:
  mapper-locations: classpath:/mappers/*.xml
  global-config:
    db-config:
      id-type: auto
      logic-delete-value: 1 #逻辑删除值(默认为1)
      logic-not-delete-value: 0 #逻辑未删除值(默认为0)

logging:
  level:
    com.xd.cubemall: debug

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.2.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <artifactId>chubemall-search</artifactId>
    <packaging>jar</packaging>

    <name>chubemall-search</name>
    <url>http://maven.apache.org</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
        <spring-cloud.version>Greenwich.SR3</spring-cloud.version>
        <elasticsearch.version>7.10.2</elasticsearch.version>
    </properties>



    <dependencies>
<!--        <dependency>-->
<!--            <groupId>junit</groupId>-->
<!--            <artifactId>junit</artifactId>-->
<!--            <version>3.8.1</version>-->
<!--            <scope>test</scope>-->
<!--        </dependency>-->

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
            <scope>provided</scope>
        </dependency>

        <!--引入common公共模块-->
        <dependency>
            <groupId>com.xd.cubemall</groupId>
            <artifactId>cubemall-common</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>



        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
        </dependency>

<!--        <dependency>-->
<!--            <groupId>org.elasticsearch.client</groupId>-->
<!--            <artifactId>elasticsearch-rest-high-level-client</artifactId>-->
<!--            <version>7.10.2</version>-->
<!--        </dependency>-->


        <!--阿里云OSS-->
        <!--        <dependency>-->
        <!--            <groupId>com.aliyun.oss</groupId>-->
        <!--            <artifactId>aliyun-sdk-oss</artifactId>-->
        <!--            <version>3.17.4</version>-->
        <!--        </dependency>-->


    </dependencies>


    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>


        </dependencies>
    </dependencyManagement>
</project>


SpuInfoController.java

package com.xd.cubemall.search.controller;


import com.xd.cubemall.common.utils.R;
import com.xd.cubemall.search.service.SpuInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(("/spuinfo"))
public class SpuInfoController {
    @Autowired
    private SpuInfoService spuInfoService;
    private volatile boolean executeFlag = false;

    @GetMapping("putonsale/{spuId}")
    public R putOnSale(@PathVariable("spuId") Long spuId){
        R r = spuInfoService.putOnSale(spuId);
        return r;
    }

    /**
     * 商品数据全量同步
     * @return
     */
    @GetMapping("/syncSpuInfo")
    public R syncSpuInfo() {
        if (!executeFlag) {
            synchronized (this) {
                if (!executeFlag) {
                    executeFlag = true;
                    R r = spuInfoService.syncSpuInfo();
                    return r;
                }
            }

        }
        return R.ok("数据正导入中,请勿重复执行");


    }

}

SpuInfoDao.java

package com.xd.cubemall.search.dao;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xd.cubemall.search.entity.SpuInfoEntity;
import com.xd.cubemall.search.model.SpuInfo;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

/**
 * spu信息
 * 
 * @author xuedong
 * @email email@gmail.com
 * @date 2024-08-13 01:36:04
 */
@Mapper
public interface SpuInfoDao extends BaseMapper<SpuInfoEntity> {
    SpuInfo getSpuInfoById(Long spuId);
    List<SpuInfo> getSpuInfoList();
	
}

SpuInfoEntity.java

package com.xd.cubemall.search.entity;

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;

/**
 * spu信息
 * 
 * @author xuedong
 * @email email@gmail.com
 * @date 2024-08-13 01:36:04
 */
@Data
@TableName("tb_spu_info")
public class SpuInfoEntity implements Serializable {
	private static final long serialVersionUID = 1L;

	/**
	 * 自增ID
	 */
	@TableId
	private Long id;
	/**
	 * spu名称
	 */
	private String spuName;
	/**
	 * spu描述
	 */
	private String spuDescription;
	/**
	 * 分类ID
	 */
	private Long categoryId;
	/**
	 * 品牌ID
	 */
	private Long brandId;
	/**
	 * 权重
	 */
	private BigDecimal weight;
	/**
	 * 发布状态
	 */
	private Integer publishStatus;
	/**
	 * 
	 */
	private Date createTime;
	/**
	 * 
	 */
	private Date updateTime;

}

SpuInfoRepository.java

package com.xd.cubemall.search.repository;

import com.xd.cubemall.search.model.SpuInfo;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;

public interface SpuInfoRepository extends ElasticsearchRepository<SpuInfo,Long> {
}

SpuInfoServiceImpl.java

package com.xd.cubemall.search.service.impl;

import com.xd.cubemall.common.utils.R;
import com.xd.cubemall.search.dao.SpuInfoDao;
import com.xd.cubemall.search.model.SpuInfo;
import com.xd.cubemall.search.repository.SpuInfoRepository;
import com.xd.cubemall.search.service.SpuInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class SpuInfoServiceImpl implements SpuInfoService {

    @Autowired
    private SpuInfoDao spuInfoDao;
    @Autowired
    private SpuInfoRepository spuInfoRepository;

    @Override
    public R putOnSale(long spuId) {
//        1.根据spuId查询对象的商品数据
        SpuInfo spuInfo = spuInfoDao.getSpuInfoById(spuId);

//        2.商品数据包含的字段 Entity中包含的字段
//        3.使用ElasticSearchRepository对象将数据添加到索引库中
        spuInfoRepository.save(spuInfo);
//        4.返回结果
        return R.ok();
    }


    @Override
    public R syncSpuInfo() {
//        1) 把所有的商品数据查询出来
        List<SpuInfo> infoList = spuInfoDao.getSpuInfoList();

//        2) 把商品数据导入到ES中
        spuInfoRepository.saveAll(infoList);
        //返回结果
        return R.ok();
    }
}

CubemallSearchApplication.java

package com.xd.cubemall.search;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication
@MapperScan("com.xd.cubemall.search.dao")
public class CubemallSearchApplication{
    public static void main(String[] args) {
        SpringApplication.run(CubemallSearchApplication.class);
    }
}

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

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

相关文章

LabVIEW智能螺杆空压机测试系统

基于LabVIEW软件开发的螺杆空压机测试系统利用虚拟仪器技术进行空压机的性能测试和监控。系统能够实现对螺杆空压机关键性能参数如压力、温度、流量、转速及功率的实时采集与分析&#xff0c;有效提高测试效率与准确性&#xff0c;同时减少人工操作&#xff0c;提升安全性。 项…

智能指针(3)

目录 可能问题五&#xff1a; 问题分析&#xff1a; 答案格式&#xff1a; shared_ptr的模拟实现 部分1&#xff1a;引用计数的设计(分考点1) 代码实现&#xff1a; 部分2&#xff1a;作为类所必须的部分(分考点2) 代码实现&#xff1a; 部分3&#xff1a;拷贝构造函数…

河北工业大学《2021年+2020年980自动控制原理真题》 (完整版)

本文内容&#xff0c;全部选自自动化考研联盟的&#xff1a;《河北工业大学980自控考研资料》的真题篇&#xff0c;真题年份为2004-最新一年。后续会持续更新更多学校&#xff0c;更多年份的真题&#xff0c;记得关注哦~ 目录 2021年真题 2020年真题 Part1&#xff1a;2021年…

Data+AI下的数据湖和湖仓一体发展史

DataAI下的数据湖和湖仓一体发展史 前言数据湖的“前世今生”AI时代的救星&#xff1a;湖仓一体湖仓一体实践演进未来趋势&#xff1a;智能化、实时化结语 前言 数据湖&#xff1f;湖仓一体&#xff1f;这是什么高科技新名词&#xff1f; 别急&#xff0c;我们慢慢聊。想象一…

DBeaver导出数据表结构和数据,导入到另一个环境数据库进行数据更新

在工作中&#xff0c;我们会进行不同环境之间数据库的数据更新&#xff0c;这里使用DBeaver导出新的数据表结构和数据&#xff0c;并执行脚本&#xff0c;覆盖另一个环境的数据库中对应数据表&#xff0c;完成数据表的更新。 一、导出 右键点击选中想要导出的数据表&#xff0…

parent参数

一、parent参数 parent参数除了有之前父窗口的界面效果外&#xff0c;还体现了Qt的内存管理策略。parent参数的对象是当前创建的对象的父对象。因此在Qt中存在父对象与子对象的概念&#xff0c;需要注意的是&#xff0c;此处的父子关系与继承无关&#xff0c;至于parent参数有关…

UNION 联合查询

1.UNION ALL联合查询 同样为了演示方便&#xff0c;先向 teacher 表插入多条测试数据&#xff1a; INSERT INTO teacher (name,age,id_number,email) VALUES (姓名一,17,42011720200604077X,NULL), (姓名二,18,42011720200604099X,123qq.com), (姓名三,19,42011720200604020X…

Web 应用防火墙(WAF)

在现代Web应用开发中&#xff0c;Nginx作为反向代理的架构被广泛采用。这种架构具备高性能、易扩展的特点&#xff0c;但也带来了Web层的安全挑战。Web应用防火墙&#xff08;WAF&#xff09;作为专门防御Web应用层攻击的安全措施&#xff0c;能够为此架构增加一层强有力的保护…

服务器托管的优缺点有哪些?

由于数字化程度不断提高&#xff0c;服务器在日常业务中发挥着越来越重要的作用。在大多数情况下&#xff0c;服务器由公司自己维护和管理。但对于一些公司来说&#xff0c;托管服务器(将这些任务交给专业人员)是更好的选择。 关于服务器的优缺点&#xff0c;有一点是明确的&am…

Centos7 安装升级最新版Redis7.4.1

1. 前言 今天阿里云云盾检测出一个redis低版本的漏洞,需要升级到稳定高版本修复漏洞,升级过程遇到了一些坑,特记录分享给大家,原服务器默认yum源安装的gcc 是4.8.5 ,默认安装redis是 3.2.12(如下图): 2.升级GCC 升级新版redis需要更高级的gcc支持,这里我们就选择升级…

打包使用pythn编写的maya插件,使用pyeal打包

1.安装python,注意版本一定要和maya上面的python解释器版本一致 2.安装pyeal使用pycharm或者maya自带的python解释器mayapy.exe 3.如果有别的库&#xff0c;下载安装到你需要的文件夹中&#xff1a; 使用mayapy: "D:\AnZhuangBao\maya2022\2022\maya2022AZ\Maya2022\bin\m…

第二百八十八节 JPA教程 - JPA查询连接OrderBy示例

JPA教程 - JPA查询连接OrderBy示例 以下代码显示如何使用ORDER BY子句和连接条件。 List l em.createQuery("SELECT e " "FROM Project p JOIN p.employees e " "WHERE p.name :project " "ORDER BY e.name").setParameter("pr…

国产AI逆袭!零一万物新模型Yi-Lightning超越 GPT-4o

近日&#xff0c;由全球千万用户盲测投票产生的 AI 模型排行榜公布&#xff0c;国产 AI 模型“Yi-Lightning”逆袭&#xff0c;超越了此前长期占据榜首的 GPT-4。 “Yi-Lightning”模型由国内知名 AI 公司零一万物研发&#xff0c;在多个分榜中均名列前茅&#xff0c;其中数学…

R语言机器学习算法实战系列(六)K-邻近算法 (K-Nearest Neighbors)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍教程下载数据加载R包导入数据数据预处理数据描述数据切割调节参数构建模型预测测试数据评估模型模型准确性混淆矩阵模型评估指标ROC CurvePRC Curve保存模型总结系统信息介绍 K-邻…

从传统到智能,从被动监控到主动预警,解锁视频安防平台EasyCVR视频监控智能化升级的关键密钥

视频监控技术从传统监控到智能化升级的过程是一个技术革新和应用场景拓展的过程。智能视频监控系统通过集成AI和机器学习算法&#xff0c;能够实现行为分析、人脸识别和异常事件检测等功能&#xff0c;提升了监控的准确性和响应速度。这些系统不仅用于传统的安全防护&#xff0…

KPaaS集成平台中怎么创建数据可视化大屏

KPaaS集成平台的数据可视化大屏是什么&#xff1f; 在KPaaS业务集成扩展平台中&#xff0c;数据大屏是一种数据可视化展示工具&#xff0c;它可以帮助企业将复杂的数据以直观、易理解的方式呈现出来&#xff0c;从而提高数据的可读性和价值。数据大屏的主要特点包括&#xff1…

PROFINET开发或EtherNet/IP开发嵌入式板有用于工业称重秤

这是一个真实案例&#xff0c;不过客户选择不透露其品牌名称。稳联技术的嵌入式解决方案助力工业称重设备制造商连接至任意工业网络。多网络连接使得称重设备能够轻松接入不同的控制系统&#xff0c;进而加快产品的上市时间。 我们找到了稳联技术的解决方案。他们成熟的技术与专…

【厦门大学附属第一医院(互联网医院)-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

实验23:DA呼吸灯实验

电路硬件: 实现功能: 代码: public.h #ifndef _public_H #define _public_H#include "reg52.h" //#include "key.h"typedef unsigned int u16; typedef unsigned char u8;void delay_10us(u16 n); void delay_ms(u16 ms);#endif public.c #include …

线性代数学习

1.标量由只有一个元素的张量表示 import torchx torch.tensor([3,0]) y torch.tensor([2,0])x y, x * y, x / y, x**y 2.可以将向量视为标量值组成的列表 x torch.arange(4) x 3.通过张量的索引访问任一元素 x[3] 4.访问张量长度 len(x) 5.只有一个轴的张量&#xff0c…