当前位置:   article > 正文

Springcloud Alibaba 使用Canal将MySql数据实时同步到Elasticsearch

Springcloud Alibaba 使用Canal将MySql数据实时同步到Elasticsearch

本篇文章在Springcloud Alibaba使用Canal将Mysql数据实时同步到Redis保证缓存的一致性-CSDN博客

基础上使用canal将mysql数据实时同步到Elasticsearch

1. 数据库准备

  1. CREATE DATABASE /*!32312 IF NOT EXISTS*/`shop` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;
  2. USE `shop`;
  3. /*Table structure for table `sku` */
  4. DROP TABLE IF EXISTS `sku`;
  5. CREATE TABLE `sku` (
  6. `id` VARCHAR(60) NOT NULL COMMENT '商品id',
  7. `name` VARCHAR(200) NOT NULL COMMENT 'SKU名称',
  8. `price` INT NOT NULL DEFAULT '1' COMMENT '价格(分)',
  9. `num` INT DEFAULT '100' COMMENT '库存数量',
  10. `image` VARCHAR(200) DEFAULT NULL COMMENT '商品图片',
  11. `images` VARCHAR(2000) DEFAULT NULL COMMENT '商品图片列表',
  12. `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  13. `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  14. `spu_id` VARCHAR(60) DEFAULT NULL COMMENT 'SPUID',
  15. `category_id` INT DEFAULT NULL COMMENT '类目ID',
  16. `category_name` VARCHAR(200) DEFAULT NULL COMMENT '类目名称',
  17. `brand_id` INT DEFAULT NULL COMMENT '品牌id',
  18. `brand_name` VARCHAR(100) DEFAULT NULL COMMENT '品牌名称',
  19. `sku_attribute` VARCHAR(200) DEFAULT NULL COMMENT '规格',
  20. `status` INT DEFAULT '1' COMMENT '商品状态 1-正常,2-下架,3-删除',
  21. PRIMARY KEY (`id`),
  22. KEY `cid` (`category_id`),
  23. KEY `status` (`status`),
  24. KEY `updated` (`update_time`)
  25. ) ENGINE=INNODB DEFAULT CHARSET=utf8mb3 COMMENT='商品表';
  26. /*Data for the table `sku` */
  27. INSERT INTO `sku`(`id`,`name`,`price`,`num`,`image`,`images`,`create_time`,`update_time`,`spu_id`,`category_id`,`category_name`,`brand_id`,`brand_name`,`sku_attribute`,`status`) VALUES
  28. ('1318594982227025922','华为Mate40 Pro 32G',114,1228,'https://sklll.oss-cn-beijing.aliyuncs.com/secby/af1faf56-b10a-4700-9896-3143a2d1c40f.jpg','https://sklll.oss-cn-beijing.aliyuncs.com/secby/a65bfbe4-21b7-42b2-b5cf-47a9730e0a16.jpg,https://sklll.oss-cn-beijing.aliyuncs.com/secby/fa52ef66-7724-4d6e-bece-15eba0f8f903.jpg,https://sklll.oss-cn-beijing.aliyuncs.com/secby/734f0f17-ac73-45d3-a6bf-83e1569ce887.jpg','2020-10-20 16:48:37','2023-12-29 19:02:16','1318594982147334146',11159,'软件研发',11,'华为','{\"就业薪资\":\"10K起\",\"学习费用\":\"2万\"}',1),
  29. ('1318596430360813570','华为Mate40 Pro 32G 1800万像素',112,1227,'https://sklll.oss-cn-beijing.aliyuncs.com/secby/9247d041-e940-426c-8e50-06084b631063.jpg','https://sklll.oss-cn-beijing.aliyuncs.com/secby/5f5b7435-6cf2-4797-8f65-d4abff181390.jpg','2020-10-20 16:54:22','2023-12-29 19:07:47','1318596430293704706',11159,'软件研发',11,'华为','{\"就业薪资\":\"10K起\",\"学习费用\":\"2万\"}',1),
  30. ('1318596430398562305','华为Mate40 Pro 128G',111,1226,'https://sklll.oss-cn-beijing.aliyuncs.com/secby/900a3618-9884-4778-bad9-c6c31eaf3eab.jpg','https://sklll.oss-cn-beijing.aliyuncs.com/secby/5f5b7435-6cf2-4797-8f65-d4abff181390.jpg','2020-10-20 16:54:22','2023-12-29 19:11:28','1318596430293704706',11159,'软件研发',11,'华为','{\"就业薪资\":\"10K起\",\"学习费用\":\"2万\"}',1),
  31. ('1318599511605563394','格力手机 5G手机',100,1225,'https://sklll.oss-cn-beijing.aliyuncs.com/secby/2b233c6a-5acc-449e-ba3a-70a506100948.jpg','https://sklll.oss-cn-beijing.aliyuncs.com/secby/ffc66a17-edfc-43bb-8f66-431b1e9bf606.jpg','2020-10-20 17:06:37','2023-12-29 19:11:25','1318599511492317185',11159,'软件研发',11,'华为','{\"就业薪资\":\"10K起\",\"学习费用\":\"2万\"}',1),
  32. ('1318599511647506433','格力手机 5G手机 红色',789,1224,'https://sklll.oss-cn-beijing.aliyuncs.com/secby/1c1fbfea-af9f-49e7-b89b-35e751874399.jpg','https://sklll.oss-cn-beijing.aliyuncs.com/secby/ffc66a17-edfc-43bb-8f66-431b1e9bf606.jpg','2020-10-20 17:06:37','2020-10-20 17:06:37','1318599511492317185',11159,'软件研发',11,'华为','{\"就业薪资\":\"10K起\",\"学习费用\":\"2万\"}',1),

 2. 公共部分

公共包

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-web</artifactId>
  4. </dependency>
  5. <!--MyBatis Plus-->
  6. <dependency>
  7. <groupId>com.baomidou</groupId>
  8. <artifactId>mybatis-plus-boot-starter</artifactId>
  9. <version>3.3.2</version>
  10. </dependency>
  11. <!--MySQL-->
  12. <dependency>
  13. <groupId>mysql</groupId>
  14. <artifactId>mysql-connector-java</artifactId>
  15. <scope>runtime</scope>
  16. </dependency>
  17. <!--Nacos-->
  18. <dependency>
  19. <groupId>com.alibaba.cloud</groupId>
  20. <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
  21. </dependency>
  22. <dependency>
  23. <groupId>com.alibaba.cloud</groupId>
  24. <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
  25. </dependency>
  26. <dependency>
  27. <groupId>javax.persistence</groupId>
  28. <artifactId>persistence-api</artifactId>
  29. <version>1.0</version>
  30. <scope>compile</scope>
  31. </dependency>

实体类Sku

@Column注解

用来标识实体类中属性与数据表中字段的对应关系

name
定义了被标注字段在数据库表中所对应字段的名称;由于驼峰命名法,如果不使用@Column字段,canal在监控数据变化时,获得的实体类部分字段为null,比如create_time等等。

  1. @TableName(value ="sku")
  2. @Data
  3. @Table
  4. public class Sku implements Serializable {
  5. @TableId(type = IdType.ASSIGN_ID)
  6. private String id;
  7. private String name;
  8. private Integer price;
  9. private Integer num;
  10. private String image;
  11. private String images;
  12. @Column(name = "create_time")
  13. private Date createTime;
  14. @Column(name = "update_time")
  15. private Date updateTime;
  16. @Column(name = "spu_id")
  17. private String spuId;
  18. @Column(name = "category_id")
  19. private Integer categoryId;
  20. @Column(name = "category_name")
  21. private String categoryName;
  22. @Column(name = "brand_id")
  23. private Integer brandId;
  24. @Column(name = "brand_name")
  25. private String brandName;
  26. @Column(name = "sku_attribute")
  27. private String skuAttribute;
  28. private Integer status;
  29. private static final long serialVersionUID = 1L;
  30. }

实体类SkuEs

  1. @Data
  2. @Document(indexName = "skusearch")//indexName一定全小写,不然出错
  3. public class SkuEs {
  4. @Id
  5. private String id;
  6. @Field(type = FieldType.Text,analyzer = "ik_smart",searchAnalyzer = "ik_smart")
  7. private String name;
  8. private Integer price;
  9. private Integer num;
  10. private String image;
  11. private String images;
  12. private Date createTime;
  13. private Date updateTime;
  14. private String spuId;
  15. private Integer categoryId;
  16. //Keyword:不分词
  17. @Field(type= FieldType.Keyword)
  18. private String categoryName;
  19. private Integer brandId;
  20. @Field(type=FieldType.Keyword)
  21. private String brandName;
  22. @Field(type=FieldType.Keyword)
  23. private String skuAttribute;
  24. private Integer status;
  25. }

3. mall-search-service

导入依赖:

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
  4. <version>2.6.3</version>
  5. </dependency>

这里使用的springboot版本为2.7.12,springboot和spring-boot-starter-data-elasticsearch的版本问题会导致异常:

java.lang.NoSuchFieldError: INDEX_CONTENT_TYPE

bootstrap.yaml代码如下:

  1. server:
  2. port: 8084
  3. spring:
  4. application:
  5. name: mall-search
  6. cloud:
  7. nacos:
  8. config:
  9. file-extension: yaml
  10. server-addr: localhost:8848
  11. discovery:
  12. #Nacos的注册地址
  13. server-addr: localhost:8848
  14. #Elasticsearch服务配置 6.8.12
  15. elasticsearch:
  16. uris: http://localhost:9200

编写SkuSearchMapper,在主启动类上添加@EnableElasticsearchRepositories(basePackages = {"xx"}),basePackages指定mapper包路径

  1. public interface SkuSearchMapper extends ElasticsearchRepository<SkuEs,String> {
  2. }

Service层

  1. public interface SkuSearchService {
  2. void add(SkuEs skuEs);
  3. void del(String id);
  4. }
  5. @Service
  6. public class SkuSearchServiceImpl implements SkuSearchService {
  7. @Autowired
  8. SkuSearchMapper skuSearchMapper;
  9. @Autowired
  10. ElasticsearchRestTemplate elasticsearchRestTemplate;
  11. @Override
  12. public void add(SkuEs skuEs) {
  13. skuSearchMapper.save(skuEs);
  14. }
  15. @Override
  16. public void del(String id) {
  17. skuSearchMapper.deleteById(id);
  18. }
  19. }

controller层

  1. @RestController
  2. @RequestMapping(value = "/search")
  3. public class SkuSearchController {
  4. @Autowired
  5. private SkuSearchService skuSearchService;
  6. /*****
  7. * 增加索引
  8. */
  9. @PostMapping(value = "/add")
  10. public RespResult add(@RequestBody SkuEs skuEs){
  11. skuSearchService.add(skuEs);
  12. return RespResult.ok();
  13. }
  14. /***
  15. * 删除索引
  16. */
  17. @DeleteMapping(value = "/del/{id}")
  18. public RespResult del(@PathVariable(value = "id")String id){
  19. skuSearchService.del(id);
  20. return RespResult.ok();
  21. }
  22. }

4. mall-canal-service

基于上一篇文章Springcloud Alibaba使用Canal将Mysql数据实时同步到Redis保证缓存的一致性-CSDN博客的canal服务。

添加以下代码:

feign接口

  1. @FeignClient(value = "mall-search")
  2. public interface SkuSearchFeign {
  3. @PostMapping(value = "/search/add")
  4. RespResult add(@RequestBody SkuEs skuEs);
  5. /***
  6. * 删除索引
  7. */
  8. @DeleteMapping(value = "/search/del/{id}")
  9. RespResult del(@PathVariable(value = "id")String id);
  10. }

 canal设计代码如下:

  1. @Component
  2. @CanalTable(value = "sku")
  3. public class SkuSearchHandler implements EntryHandler<Sku> {
  4. @Autowired
  5. SkuSearchFeign skuSearchFeign;
  6. @Override
  7. public void insert(Sku sku) {
  8. System.out.println(sku);
  9. String jsonString = JSON.toJSONString(sku);
  10. SkuEs skuEs = JSON.parseObject(jsonString, SkuEs.class);
  11. skuSearchFeign.add(skuEs);
  12. }
  13. @Override
  14. public void update(Sku before, Sku after) {
  15. System.out.println(after);
  16. String jsonString = JSON.toJSONString(after);
  17. SkuEs skuEs = JSON.parseObject(jsonString, SkuEs.class);
  18. System.out.println(skuEs);
  19. skuSearchFeign.add(skuEs);
  20. }
  21. @Override
  22. public void delete(Sku sku) {
  23. System.out.println(sku);
  24. skuSearchFeign.del(sku.getId());
  25. }
  26. }

 

 

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号