通过自定义注解的形式,对JdbcSink进行封装,支持自动建表、自动拼接insert语句
主类
package flink.security.sink;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import lombok.Cleanup;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.flink.connector.jdbc.JdbcConnectionOptions;
import org.apache.flink.connector.jdbc.JdbcExecutionOptions;
import org.apache.flink.connector.jdbc.JdbcSink;
import org.apache.flink.connector.jdbc.JdbcStatementBuilder;
import org.apache.flink.streaming.api.functions.sink.SinkFunction;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 通用clickhouse sink
*/
@Slf4j
public class SecurityClickHouseSink {
public static <T> SinkFunction<T> getSink(Class<T> model) throws Exception {
createTable(model);
String sql = createSql(model);
return JdbcSink.sink(
sql,
new JdbcStatementBuilder<T>() {
@SneakyThrows
@Override
public void accept(PreparedStatement preparedStatement, T t) throws SQLException {
Class<?> obj = t.getClass();
Field[] declaredFields = obj.getDeclaredFields();
Stream<Field> usedFields = getUsedFields(declaredFields);
List<Field> fields = usedFields.collect(Collectors.toList());
for (int i = 0; i < fields.size(); i++) {
fields.get(i).setAccessible(true);
Object o = fields.get(i).get(t);
if (o instanceof Boolean) {
preparedStatement.setInt(i + 1, (Boolean) o ? 1 : 0);
} else if (o instanceof List) {

该代码示例展示了如何通过自定义注解`SecurityTable`和`SecurityField`,对ApacheFlink的JdbcSink进行封装,以支持自动建表和动态生成`INSERT`语句。在Java中,这个通用的`SecurityClickHouseSink`类处理了与ClickHouse数据库的连接,根据模型类自动创建表结构,并根据模型字段生成SQL插入语句,特别适用于处理包含日期、布尔值和列表等类型的数据。整个过程优化了数据集成到ClickHouse的流程。
最低0.47元/天 解锁文章
3700

被折叠的 条评论
为什么被折叠?



