실제로 JDBC 커넥터도 삭제 문을 실행합니다. update_before 및 delete type 메시지를 수신한 후 DDL에 구성된 기본 키에 따라 delete 문이 생성 및 실행되며 where 조건의 필드는 기본 키입니다.
먼저 공식 웹사이트의 내용을 살펴보겠습니다.
기본 키가 DDL에 정의된 경우 JDBC 수신기는 일반 INSERT 문 대신 upsert 의미 체계를 사용합니다. Upsert 의미 체계는 멱등성을 제공하는 기본 데이터베이스에 고유한 제약 조건 위반이 있는 경우 자동으로 새 행을 추가하거나 기존 행을 업데이트하는 것을 말합니다.
upsert에 대한 표준 구문이 없으므로 다음 표에서는 사용되는 데이터베이스별 DML에 대해 설명합니다.
이것은 데이터를 삽입하기 위한 것일 뿐 실제로는 JDBC 커넥터도 delete 문을 실행하게 됩니다. update_before 및 delete type 메시지를 수신한 후 DDL에 구성된 기본 키에 따라 delete 문이 생성 및 실행되며 where 조건의 필드는 기본 키입니다.
다음은 TableBufferReducedStatementExecutor 클래스의 핵심 로직입니다.
@Override
public void addToBatch(RowData record) throws SQLException {
RowData key = keyExtractor.apply(record);
boolean flag = changeFlag(record.getRowKind());
RowData value = valueTransform.apply(record); // copy or not
reduceBuffer.put(key, Tuple2.of(flag, value));
}
/**
* Returns true if the row kind is INSERT or UPDATE_AFTER, returns false if the row kind is
* DELETE or UPDATE_BEFORE.
*/
private boolean changeFlag(RowKind rowKind) {
switch (rowKind) {
case INSERT:
case UPDATE_AFTER:
return true;
case DELETE:
case UPDATE_BEFORE:
return false;
default:
throw new UnsupportedOperationException(
String.format(
"Unknown row kind, the supported row kinds is: INSERT, UPDATE_BEFORE, UPDATE_AFTER,"
+ " DELETE, but get: %s.",
rowKind));
}
}
@Override
public void executeBatch() throws SQLException {
for (Map.Entry<RowData, Tuple2<Boolean, RowData>> entry : reduceBuffer.entrySet()) {
if (entry.getValue().f0) {
upsertExecutor.addToBatch(entry.getValue().f1);
} else {
// delete by key
deleteExecutor.addToBatch(entry.getKey());
}
}
upsertExecutor.executeBatch();
deleteExecutor.executeBatch();
reduceBuffer.clear();
}