(4)FlinkSQL将socket数据写入到mysql方式一

本章节主要演示从socket接收数据,通过滚动窗口每30秒运算一次窗口数据,然后将结果写入Mysql数据库
在这里插入图片描述
(1)准备一个实体对象,消息对象

package com.pojo;

import java.io.Serializable;

/**
 * Created by lj on 2022-07-05.
 */
public class WaterSensor implements Serializable {
    private String id;
    private long ts;
    private int vc;

    public WaterSensor(){

    }

    public WaterSensor(String id,long ts,int vc){
        this.id = id;
        this.ts = ts;
        this.vc = vc;
    }

    public int getVc() {
        return vc;
    }

    public void setVc(int vc) {
        this.vc = vc;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public long getTs() {
        return ts;
    }

    public void setTs(long ts) {
        this.ts = ts;
    }
}

(2)编写socket代码,模拟数据发送

package com.producers;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Random;

/**
 * Created by lj on 2022-07-05.
 */
public class Socket_Producer {
    public static void main(String[] args) throws IOException {

        try {
            ServerSocket ss = new ServerSocket(9999);
            System.out.println("启动 server ....");
            Socket s = ss.accept();
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(s.getOutputStream()));
            String response = "java,1,2";

            //每 2s 发送一次消息
            int i = 0;
            Random r=new Random();   
            String[] lang = {"flink","spark","hadoop","hive","hbase","impala","presto","superset","nbi"};

            while(true){
                Thread.sleep(2000);
                response= lang[r.nextInt(lang.length)] + "," + i + "," + i+"\n";
                System.out.println(response);
                try{
                    bw.write(response);
                    bw.flush();
                    i++;
                }catch (Exception ex){
                    System.out.println(ex.getMessage());
                }

            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

(3)从socket端接收数据,并设置30秒触发执行一次窗口运算

package com.examples;

import com.pojo.WaterSensor;
import com.sinks.RetractStream_Mysql;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.table.api.Table;
import org.apache.flink.table.api.bridge.java.StreamTableEnvironment;
import org.apache.flink.types.Row;

import static org.apache.flink.table.api.Expressions.$;

/**
 * Created by lj on 2022-07-06.
 */

public class Flink_Group_Window_Tumble_Sink_Mysql {
    public static void main(String[] args) throws Exception {

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        env.setParallelism(1);
        StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);
        DataStreamSource<String> streamSource = env.socketTextStream("127.0.0.1", 9999,"\n");
        SingleOutputStreamOperator<WaterSensor> waterDS = streamSource.map(new MapFunction<String, WaterSensor>() {
            @Override
            public WaterSensor map(String s) throws Exception {
                String[] split = s.split(",");
                return new WaterSensor(split[0], Long.parseLong(split[1]), Integer.parseInt(split[2]));
            }
        });

        // 将流转化为表
        Table table = tableEnv.fromDataStream(waterDS,
                $("id"),
                $("ts"),
                $("vc"),
                $("pt").proctime());

        tableEnv.createTemporaryView("EventTable", table);

        Table result = tableEnv.sqlQuery(
                "SELECT " +
                        "id, " +                //window_start, window_end,
                        "COUNT(ts) ,SUM(ts)" +
                        "FROM TABLE( " +
                        "TUMBLE( TABLE EventTable , " +
                        "DESCRIPTOR(pt), " +
                        "INTERVAL '30' SECOND)) " +
                        "GROUP BY id , window_start, window_end"
        );

        tableEnv.toRetractStream(result, Row.class).addSink(new RetractStream_Mysql()); 
        env.execute();
    }
}

(4)定义一个写入到mysql的sink

package com.sinks;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.streaming.api.functions.sink.RichSinkFunction;
import org.apache.flink.types.Row;

/**
 * Created by lj on 2022-07-06.
 */
public class RetractStream_Mysql  extends RichSinkFunction<Tuple2<Boolean, Row>> {

    private static final long serialVersionUID = -4443175430371919407L;
    PreparedStatement ps;
    private Connection connection;

    /**
     * open() 方法中建立连接,这样不用每次 invoke 的时候都要建立连接和释放连接
     *
     * @param parameters
     * @throws Exception
     */
    @Override
    public void open(Configuration parameters) throws Exception {
        super.open(parameters);
        connection = getConnection();
    }

    @Override
    public void close() throws Exception {
        super.close();
        //关闭连接和释放资源
        if (connection != null) {
            connection.close();
        }
        if (ps != null) {
            ps.close();
        }
    }

    /**
     * 每条数据的插入都要调用一次 invoke() 方法
     *
     * @param context
     * @throws Exception
     */
    @Override
    public void invoke(Tuple2<Boolean, Row> userPvEntity, Context context) throws Exception {
        String sql = "INSERT INTO flinkcomponent(componentname,componentcount,componentsum) VALUES(?,?,?);";
        ps = this.connection.prepareStatement(sql);

        ps.setString(1,userPvEntity.f1.getField(0).toString());
        ps.setInt(2, Integer.parseInt(userPvEntity.f1.getField(1).toString()));
        ps.setInt(3, Integer.parseInt(userPvEntity.f1.getField(2).toString()));
        ps.executeUpdate();
    }

    private static Connection getConnection() {
        Connection con = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/testdb?useUnicode=true&characterEncoding=UTF-8&useSSL=false","root","root");
        } catch (Exception e) {
            System.out.println("-----------mysql get connection has exception , msg = "+ e.getMessage());
        }
        return con;
    }
}

(5)效果演示,每30秒往数据库写一次数据
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要将Flink实时计算的结果写入MySQL数据库中,可以使用Flink的JDBC连接器。以下是一个将当天PV写入MySQL的示例代码: ```java // 定义MySQL连接信息 final String jdbcUrl = "jdbc:mysql://localhost:3306/test"; final String username = "root"; final String password = "root"; // 定义Flink数据流环境 StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 读取数据流 DataStream<String> input = env.socketTextStream("localhost", 9999); // 对数据流进行处理,计算当天PV DataStream<Tuple2<String, Integer>> result = input .map(new MapFunction<String, Tuple2<String, Integer>>() { @Override public Tuple2<String, Integer> map(String value) throws Exception { // 解析日志数据,获取访问时间和页面URL String[] fields = value.split(","); String time = fields[0]; String url = fields[1]; // 计算当天日期 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); String today = sdf.format(new Date()); // 判断日志时间是否在当天,如果是则返回页面URL和1,否则返回空 if (time.contains(today)) { return new Tuple2<>(url, 1); } else { return null; } } }) .filter(Objects::nonNull) .keyBy(0) .sum(1); // 将结果写入MySQL result.addSink(JdbcSink.sink( "insert into pv(url, pv, date) values (?, ?, ?)", new JdbcStatementBuilder<Tuple2<String, Integer>>() { @Override public void accept(PreparedStatement preparedStatement, Tuple2<String, Integer> t) throws SQLException { // 设置SQL参数 preparedStatement.setString(1, t.f0); preparedStatement.setInt(2, t.f1); preparedStatement.setDate(3, new Date(System.currentTimeMillis())); } }, new JdbcConnectionOptions.JdbcConnectionOptionsBuilder() .withUrl(jdbcUrl) .withUsername(username) .withPassword(password) .build())); // 启动数据流处理 env.execute(); ``` 该代码首先定义了MySQL的连接信息,然后创建了一个数据流环境,并从Socket读取数据流进行处理。处理过程中,首先解析日志数据,判断是否在当天,并计算PV。最后,使用JdbcSink将结果写入MySQL数据库中。 需要注意的是,JdbcSink需要引入以下依赖: ```xml <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-connector-jdbc_2.11</artifactId> <version>1.12.2</version> </dependency> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NBI大数据可视化分析

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值