//TODO 获取jdbcSink的工具类 将数据写入Clickhouse
public class clickHouseUtil {
public static <T>SinkFunction<T> getJdbcSink(String sql){
SinkFunction<T> jdbcSink = JdbcSink.<T>sink(sql, new JdbcStatementBuilder<T>() {
@SneakyThrows
@Override
public void accept(PreparedStatement ps, T t) throws SQLException {
// TODO 通过反射 对象获取类的信息
Field[] fields = t.getClass().getDeclaredFields();//获取所有属性包括私有
// 除了继承的属性
int skipFields = 0;
for (int i = 0; i < fields.length; i++) {
Field field = fields[i];
TransientSink annotation = field.getAnnotation(TransientSink.class);
if (annotation != null) {
// 如果存在该注解
System.out.println("该字段不会写入Clickhouse" + field.getName());
skipFields++;
continue;//跳出本次循环
}
field.setAccessible(true);
Object o = field.get(t);//获取对象属性的值
ps.setObject(i + 1 - skipFields, o);
}
}
}, new JdbcExecutionOptions.Builder().withBatchSize(5)
.withBatchIntervalMs(5000L).withMaxRetries(3).build(),
new JdbcConnectionOptions.JdbcConnectionOptionsBuilder()
.withDriverName("ru.yandex.clickhouse.ClickHouseDriver")
.withUrl("jdbc:clickhouse://hadoop106:8123")
.build());
return jdbcSink;
}
}
通过自定义注解过滤掉我们不需要写入Clickhouse的字段
//TODO 该注解用来标识往clickhouse写入的时候不需要的字段
@Target(FIELD)//标识该注解用于属性上
@Retention(RetentionPolicy.RUNTIME)//注解保留策略
public @interface TransientSink {
}