public static List<FlatMessage> parseFlatMessage(Message message) {
try {
if (message == null) {
return null;
} else {
List<FlatMessage> flatMessages = new ArrayList();
List<CanalEntry.Entry> entries = message.getEntries();
//遍历entry entry--------->flatmessage
for (CanalEntry.Entry entry : entries) {
CanalEntry.Header header = entry.getHeader();
CanalEntry.EntryType entryType = entry.getEntryType();
//如果是事务则先忽略
if (entryType == CanalEntry.EntryType.TRANSACTIONBEGIN
|| entryType == CanalEntry.EntryType.TRANSACTIONEND) {
continue;
}
CanalEntry.EventType eventType = header.getEventType();
ByteString storeValue = entry.getStoreValue();
CanalEntry.RowChange rowChange = null;
try {
rowChange = CanalEntry.RowChange.parseFrom(storeValue);
} catch (InvalidProtocolBufferException e) {
e.printStackTrace();
}
//基本类型
FlatMessage flatMessage = new FlatMessage(message.getId());
flatMessage.setEs(header.getExecuteTime());
flatMessage.setTable(header.getTableName());
flatMessage.setDatabase(header.getSchemaName());
flatMessage.setType(eventType.toString());
flatMessage.setIsDdl(rowChange.getIsDdl());
flatMessage.setSql(rowChange.getSql());
flatMessage.setTs(System.currentTimeMillis());
if (!rowChange.getIsDdl()) {
//定义复杂类型
Map<String, Integer> sqlType = new LinkedHashMap();
Map<String, String> mysqlType = new LinkedHashMap();
List<Map<String, String>> data = new ArrayList();
List<Map<String, String>> old = new ArrayList();
Set<String> updateSet = new HashSet();
List<CanalEntry.RowData> rowDatas = rowChange.getRowDatasList();
//遍历rowDatas
for (CanalEntry.RowData rowData : rowDatas) {
//只分析insert update,delete
if (eventType != CanalEntry.EventType.INSERT && eventType != CanalEntry.EventType.UPDATE
&& eventType != CanalEntry.EventType.DELETE) {
continue;
}
Map<String, String> row = new LinkedHashMap();
List<CanalEntry.Column> columns;
if (eventType == CanalEntry.EventType.DELETE) {
columns = rowData.getBeforeColumnsList();
} else {
columns = rowData.getAfterColumnsList();
}
for (CanalEntry.Column column : columns) {
sqlType.put(column.getName(), column.getSqlType());
mysqlType.put(column.getName(), column.getMysqlType());
if (column.getIsNull()) {
row.put(column.getName(), null);
} else {
row.put(column.getName(), column.getValue());
}
// 获取update为true的字段
if (column.getUpdated()) {
updateSet.add(column.getName());
}
}
if (!row.isEmpty()) {
data.add(row);
}
//update再添加old
Map<String, String> rowOld = new LinkedHashMap<>();
if (eventType == CanalEntry.EventType.UPDATE) {
for (CanalEntry.Column column : rowData.getBeforeColumnsList()) {
if (updateSet.contains(column.getName())) {
if (column.getIsNull()) {
rowOld.put(column.getName(), null);
} else {
rowOld.put(column.getName(), column.getValue());
}
}
}
}
// update操作再添加before的值
if (!rowOld.isEmpty()) {
old.add(rowOld);
}
}
if (!sqlType.isEmpty()) {flatMessage.setSqlType(sqlType);}
if (!mysqlType.isEmpty()) { flatMessage.setMysqlType(mysqlType);}
if (!data.isEmpty()) {flatMessage.setData(data);}
if (!old.isEmpty()) {flatMessage.setOld(old);}
}
flatMessages.add(flatMessage);
}
return flatMessages;
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}