1.引入canal相关依赖
#springboot版本2.7.9
<dependency>
<groupId>com.alibaba.otter</groupId>
<artifactId>canal.client</artifactId>
<version>1.1.5</version>
</dependency>
<dependency>
<groupId>com.alibaba.otter</groupId>
<artifactId>canal.protocol</artifactId>
<version>1.1.5</version>
</dependency>```
2.application.yml配置文件
canal:
server:
ip: 你的ip
port: 11111
promotion:
destination: example
batchSize: 1000```
3.编写CanalUtil类
package com.yyy.zq.utils;
import com.alibaba.otter.canal.client.CanalConnector;
import com.alibaba.otter.canal.client.CanalConnectors;
import com.alibaba.otter.canal.protocol.CanalEntry;
import com.alibaba.otter.canal.protocol.CanalEntry.Entry;
import com.alibaba.otter.canal.protocol.CanalEntry.EntryType;
import com.alibaba.otter.canal.protocol.CanalEntry.RowChange;
import com.alibaba.otter.canal.protocol.Message;
import com.google.protobuf.InvalidProtocolBufferException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.net.InetSocketAddress;
import java.util.List;
@Slf4j
@Component
public class CanalUtil implements CommandLineRunner {
@Value("${canal.server.ip}")
private String canalServerIp;
@Value("${canal.server.port}")
private int canalServerPort;
@Value("${canal.server.username:canal}")
private String userName;
@Value("${canal.server.password:canal}")
private String password;
@Value("${canal.promotion.destination}")
private String destination;
@Override
public void run(String...args) {
CanalConnector connector =
CanalConnectors.newSingleConnector(new InetSocketAddress(canalServerIp, canalServerPort), destination, "", "");
int batchSize = 1000;
try {
connector.connect();
//connector.subscribe("zq");
connector.subscribe(".*\\..*");
connector.rollback();
try {
while (true) {
Message message = connector.getWithoutAck(batchSize);
long batchId = message.getId();
int size = message.getEntries().size();
if (batchId == -1 || size == 0) {
Thread.sleep(1000);
} else {
log.info("msgId -> " + batchId);
dataHandle(message.getEntries());
}
connector.ack(batchId);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
} finally {
connector.disconnect();
//防止频繁访问数据库链接: 线程睡眠 5秒
try {
Thread.sleep(5 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void dataHandle(List<Entry> entries) throws InvalidProtocolBufferException {
for (Entry entry : entries) {
if(entry.getEntryType() != CanalEntry.EntryType.ROWDATA){
continue;
}
if (EntryType.ROWDATA == entry.getEntryType()) {
RowChange rowChange = RowChange.parseFrom(entry.getStoreValue());
for (CanalEntry.RowData rowData : rowChange.getRowDatasList()) {
System.out.println(rowChange.getEventType());
switch (rowChange.getEventType()){
case INSERT:
// 表名
String tableName = entry.getHeader().getTableName();
List<CanalEntry.Column> afterColumnsList = rowData.getAfterColumnsList();
System.out.println(afterColumnsList);
String key = "yyy:user:";
break;
case UPDATE:
List<CanalEntry.Column> beforeColumnsList1 = rowData.getBeforeColumnsList();
System.out.println("更新前的数据是:" + beforeColumnsList1);
List<CanalEntry.Column> afterColumnsList2 = rowData.getAfterColumnsList();
System.out.println("更新后的数据是:" + afterColumnsList2);
break;
case DELETE:
List<CanalEntry.Column> beforeColumnsList = rowData.getBeforeColumnsList();
System.out.println("被删除的数据是:" + beforeColumnsList);
break;
default:
}
}
}
}
}
}
4.启动项目
操作数据库数据
控制台输出
整合完成