由于公司业务需要用到es技术,所以就需要考虑到es与数据库的同步问题,下面为记录此次操作,方便后期查看使用,话不多说,干中学,此次业务步骤主要为:
1)数据库数据发生变化的时候,将对应业务数据发送到创建好的业务队列中。
2)队列接收到数据再根据业务对es进行操作。
1、创建交换机、队列、键所用到的静态常量
因为这些数据需要经常使用,防止写错,最好用静态常量写到一个类中,后期方便调佣,此次演示业务包括数据的新增删除操作数据的同步,如下代码所示:
public class MqConstant {
//交换机
public static final String EXCHANGE_NAME = "sys_user_topic";
//新增 编辑队列
public static final String INSERT_QUEUE_NAME = "sys_user_insert_queue";
//删除队列
public static final String DELETE_QUEUE_NAME = "sys_user_delete_queue";
//新增 编辑队列绑定的key
public static final String INSERT_KEY_NAME = "sys_user_insert_key";
//删除队列绑定的key
public static final String DELETE_KEY_NAME = "sys_user_delete_key";
}
2、创建MQ针对业务对交换机。队列。key进行相关绑定(此步骤也可通过注解实现),代码如下所示:
/**
* MQ配置类
*/
@Configuration
public class MqConfig {
//交换机
@Bean
public TopicExchange exchange() {
return new TopicExchange(MqConstant.EXCHANGE_NAME);
}
//新增队列
@Bean
public Queue insertQueue() {
return new Queue(MqConstant.INSERT_QUEUE_NAME);
}
//删除队列
@Bean
public Queue deleteQueue() {
return new Queue(MqConstant.DELETE_QUEUE_NAME);
}
//新增队列键绑定
@Bean
public Binding insertBinding() {
return BindingBuilder.bind(insertQueue()).to(exchange()).with(MqConstant.INSERT_KEY_NAME);
}
//删除队列键绑定
@Bean
public Binding deleteBinding() {
return BindingBuilder.bind(deleteQueue()).to(exchange()).with(MqConstant.DELETE_KEY_NAME);
}
}
3、创建队列的接收类,根据不同业务对es进行操作,代码如下所示:
import org.example.es_demo.constants.SysUserDoc;
import org.example.es_demo.domain.SysUser;
import org.example.es_demo.service.SysUserService;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.IOException;
/**
* mq消息接收类,并针对不同业务对es进行相关操作
*/
@Component
public class MqListener {
@Autowired
private RestHighLevelClient restHighLevelClient;
@Autowired
private SysUserService sysUserService;
/**
* mq新增业务处理
* @param userId
* @throws IOException
*/
@RabbitListener(queues = MqConstant.INSERT_QUEUE_NAME)
public void insertListener(Long userId) throws IOException {
SysUser sysUser = sysUserService.getById(userId);
SysUserDoc sysUserDoc = new SysUserDoc(sysUser);
//1、准备Request对象
IndexRequest request = new IndexRequest("sys_user").id(sysUser.getUserId().toString());
//2、 准备JSon文档
request.source(JSON.toJSONString(sysUserDoc), XContentType.JSON);
//3、发送请求
restHighLevelClient.index(request, RequestOptions.DEFAULT);
}
/**
* mq删除业务处理
* @param userId
* @throws IOException
*/
@RabbitListener(queues = MqConstant.DELETE_QUEUE_NAME)
public void deleteListener(Long userId) throws IOException {
//1、准备Request对象
DeleteRequest request = new DeleteRequest("sys_user", String.valueOf(userId));
//2、发送请求
restHighLevelClient.delete(request, RequestOptions.DEFAULT);
}
}
注:连初始化es,在springboot项目使用es 需要对其进行初始化,建立连接关系,可在启动类增加Bean注解进行初始化:
@Bean public RestHighLevelClient restHighLevelClient() { return new RestHighLevelClient(RestClient.builder( new HttpHost("localhost", 9200, "http"))); }
连接mq队列,需在yml文件进行配置:
spring: rabbitmq: host: localhost port: 5672 username: guest password: guest virtual-host: /
4、以上四步是接收mq数据并进行操作,下面就是数据库发生操作的时候,我们对mq队列进行数据插入,代码如下所示:
@RestController
@RequestMapping("/sys_user")
public class SysUserController {
@Autowired
private SysUserService sysUserService;
@Autowired
private RabbitTemplate rabbitTemplate;
// 插入数据
@PostMapping("/insert")
public void insert(@RequestBody SysUser sysUser) {
sysUserService.save(sysUser);
//向队列中发送数据
rabbitTemplate.convertAndSend(MqConstant.EXCHANGE_NAME, MqConstant.INSERT_KEY_NAME, sysUser.getUserId());
}
// 删除数据
@RequestMapping("/delete")
public void delete(@RequestBody SysUser sysUser) {
sysUserService.removeById(sysUser.getUserId());
//向队列中发送数据
rabbitTemplate.convertAndSend(MqConstant.EXCHANGE_NAME, MqConstant.DELETE_KEY_NAME, sysUser.getUserId());
}
}
以上就完成了当数据库发生变化的时候,同步es中的相关数据业务,默认已经安装了mq以及es。