SpringCloudAlibaba云商场-海量数据搜索实现(三)

111 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第27天,点击查看活动详情

每日英语:

Real generosity toward the future lies in giving all to the present.

翻译:对未来真正的慷慨,是把一切都献给现在。 ——阿贝尔·加缪

1. ES索引增加和删除功能实现

1.1 mapper

创建Dao接口需要继承ElasticsearchRepository<T,ID>接口,同时需要在启动类中添加扫描注解。

创建com.xz.mall.search.mapper.SkuSearchMapper:

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

在启动类上添加EnableElasticsearchRepositories注解:

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableElasticsearchRepositories(basePackages = "com.xz.mall.search.mapper")
public class MallSearchApplication {

    public static void main(String[] args) {
        SpringApplication.run(MallSearchApplication.class, args);
    }

}

1.2 service

创建接口:com.xz.mall.search.service.SkuSearchService,创建添加和删除方法:

public interface SkuSearchService {

    /**
     * 增加索引
     * @param skuEs
     */
    void add(SkuEs skuEs);

    /**
     * 删除索引
     * @param id
     */
    void del(String id);
}

创建实现类:com.xz.mall.search.service.impl.SkuSearchServiceImpl

@Service
public class SkuSearchServiceImpl implements SkuSearchService {

    @Autowired
    private SkuSearchMapper skuSearchMapper;

    /**
     * 增加索引
     * @param skuEs
     */
    @Override
    public void add(SkuEs skuEs) {
        //获取属性
        String attrMap = skuEs.getSkuAttribute();
        if (!StringUtils.isEmpty(attrMap)) {
            //将属性添加到attrMap中
            skuEs.setAttrMap(JSON.parseObject(attrMap, Map.class));
        }
        skuSearchMapper.save(skuEs);
    }

    /**
     * 删除索引
     * @param id
     */
    @Override
    public void del(String id) {
        skuSearchMapper.deleteById(id);
    }
}

1.3 controller

创建com.xz.mall.search.controller.SkuSearchController

@RestController
@RequestMapping(value = "/search")
public class SkuSearchController {

    @Autowired
    private SkuSearchService searchService;

    /**
     * 增加索引
     */
    @PostMapping(value = "/add")
    public RespResult add(@RequestBody SkuEs skuEs) {
        searchService.add(skuEs);
        return RespResult.ok();
    }

    /**
     * 删除索引
     */
    @DeleteMapping(value = "/del/{id}")
    public RespResult deleteById(@PathVariable(value = "id") String id) {
        searchService.del(id);
        return RespResult.ok();
    }

}

1.4 feign

mall-search-api中创建com.xz.mall.search.feign.SkuSearchFeign

@FeignClient(value = "mall-search")
@RequestMapping(value = "/search")
public interface SkuSearchFeign {

    /**
     * 增加索引
     */
    @PostMapping(value = "/add")
    RespResult add(@RequestBody SkuEs skuEs);

    /**
     * 删除索引
     */
    @DeleteMapping(value = "/del/{id}")
    RespResult deleteById(@PathVariable(value = "id") String id);

}

2. 索引实时更新实现

2.1 映射配置

实时更新,我们需要在Canal微服务中调用上面2个接口,首先我们要先将数据库中通过Canal推送的数据转成指定的JavaBean,需要用到JPA注解配置映射。

mall-api中引入JPA:

<!--JPA-->
<dependency>
    <groupId>javax.persistence</groupId>
    <artifactId>persistence-api</artifactId>
    <version>1.0</version>
    <scope>compile</scope>
</dependency>

mall-goods-api中的Sku中配置映射如下:

@Data
@AllArgsConstructor
@NoArgsConstructor
//MyBatisPlus表映射注解
@TableName(value = "sku")
@Table
public class Sku implements Serializable {

    @TableId(type = IdType.ASSIGN_ID)
    private String id;
    private String name;
    private Integer price;
    private Integer num;
    private String image;
    private String images;
    @Column(name = "create_time")
    private Date createTime;
    @Column(name = "update_time")
    private Date updateTime;
    @Column(name = "spu_id")
    private String spuId;
    @Column(name = "category_id")
    private Integer categoryId;
    @Column(name = "category_name")
    private String categoryName;
    @Column(name = "brand_id")
    private Integer brandId;
    @Column(name = "brand_name")
    private String brandName;
    @Column(name = "sku_attribute")
    private String skuAttribute;
    private Integer status;
}

2.2 监听更新

监听更新需要调用search的接口,所以需要引入依赖包,在mall-canal-service添加如下依赖:

<dependency>
    <groupId>com.xz</groupId>
    <artifactId>mall-search-api</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

mall-canal-service的启动类上添加Feign注解@EnableFeignClients配置:

@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
@EnableFeignClients(basePackages = {"com.xz.mall.search.feign","com.xz.mall.goods.feign"})
public class MallCanalApplication {

    public static void main(String[] args) {
        SpringApplication.run(MallCanalApplication.class, args);
    }

}

mall-canal-service中创建com.xz.mall.canal.listener.SkuHandler

@Component
@CanalTable(value = "sku")
public class SkuHandler implements EntryHandler<Sku> {

    @Autowired
    private SkuSearchFeign skuSearchFeign;

    /**
     * 增加数据监听
     * @param sku
     */
    @Override
    public void insert(Sku sku) {
        if (sku.getStatus().intValue() == 1) {
            //将Sku转成JSON,再将JSON转成SkuES
            skuSearchFeign.add(JSON.parseObject(JSON.toJSONString(sku), SkuEs.class));
        }
    }

    /**
     * 修改数据监听
     * @param before
     * @param after
     */
    @Override
    public void update(Sku before, Sku after) {
        if (after.getStatus().intValue() == 2) {
            //删除索引
            skuSearchFeign.deleteById(after.getId());
        } else {
            //更新索引
            skuSearchFeign.add(JSON.parseObject(JSON.toJSONString(after), SkuEs.class));
        }
    }

    /**
     * 删除数据监听
     * @param sku
     */
    @Override
    public void delete(Sku sku) {
        skuSearchFeign.deleteById(sku.getId());
    }
}

修改数据库数据,同时打开http://127.0.0.1:9100/,效果如下:

ES实时更新.jpg

总结:本篇主要介绍了一下ES索引增加和删除功能实现,还有索引实时更新实现,主要用到了canal和es,当然了还有mysql。