使用自定义Sink类的方式:如下
这是使用的是Table转为DataStream,只是使用.addSink()方法
TupleTypeInfo<Tuple2<String, String>> tupleType = new TupleTypeInfo<>(STRING(), STRING());
Table mySourceTable = stEvn.from("test_source");
DataStream dataStream =stEvn.toAppendStream(mySourceTable, tupleType);
dataStream.addSink(new TestSink());
自定义Sink类,需要继承RichSinkFunction;
这里是向神通数据库插数据,其它数据库类同;
import com.alibaba.fastjson.JSONObject;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
import java.sql.*;
/**
* 继承RichSinkFunction<Tuple2<String, String>>类,
* 其中Tuple2<String, String>为source端传到sink的数据类型,这个根据Source端数据类型而定
*/
public class TestSink extends RichSinkFunction<Tuple2<String, String>> {
protected Connection connect = null;
/**
* open方法在sink第一次启动时调用,一般用于sink的初始化操作
*/
@Override
public void open(Configuration parameters) throws Exception {
super.open(parameters);
String url = "jdbc:oscar://localhost:2021/OSRDB";
String user = "SYSDBA";
String pwd = "123456";
Class.forName("com.oscar.Driver");
connect = DriverManager.getConnection(url, user, pwd);
}
/**
* invoke方法是sink数据处理逻辑的方法,source端传来的数据都在invoke方法中进行处理
* 其中invoke方法中第一个参数类型与RichSinkFunction<>中的泛型对应。
* 第二个参数为一些上下文信息
*/
@Override
public void invoke(Tuple2<String, String> value, Context context) throws Exception {
if (value.f0 != null && !"".equals(value.f0)) {
//从数据源获取到的数据,将其转换为json
JSONObject object = JSONObject.parseObject(value.f0);
//执行的sql语句
String sql = "insert into TEST_TABLE (NAME,AGE) values(?,?)";
// 创建一个Statment对象
PreparedStatement ps = connect.prepareStatement(sql);
// 为sql语句中第一个问号赋值
ps.setString(1, object.getString("name"));
// 为sql语句中第二个问号赋值
ps.setString(2, object.getString("age"));
ps.executeUpdate();
} else {
//无操作
}
}
/**
* close方法在sink结束时调用,一般用于资源的回收操作
*/
@Override
public void close() throws Exception {
if (connect != null) {
connect.close();
}
super.close();
}
}