静态表join动态表

本文介绍了一个使用Apache Flink进行实时流处理的例子,具体实现了一个全量聚合函数来计算滑动窗口内的平均温度,并将结果写入MySQL数据库。此应用展示了如何通过Flink的ProcessWindowFunction进行复杂的数据处理和聚合。
package org.example.windowfunc

import java.sql.{Connection, DriverManager, PreparedStatement, ResultSet}

import org.apache.flink.api.common.functions.{FlatMapFunction, RichFlatMapFunction}
import org.apache.flink.configuration.Configuration
import org.apache.flink.streaming.api.functions.sink.{RichSinkFunction, SinkFunction}
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.api.scala.function.ProcessWindowFunction
import org.apache.flink.streaming.api.windowing.time.Time
import org.apache.flink.streaming.api.windowing.windows.TimeWindow
import org.apache.flink.util.Collector
import org.example.source.self.{SensorReading, SensorSource}

import scala.collection.mutable
import scala.util.Random

/**
 * 全量聚合函数计算平均温度
 */
object AvgTempPerWindowByProcessWindowFunction {
  def main(args: Array[String]): Unit = {
    val env = StreamExecutionEnvironment.getExecutionEnvironment
    //    env.setParallelism(1)
    val random = new Random()
    val parallelism = env.getParallelism
    println("parallelism = " + parallelism)

    val stream = env
      .addSource(new SensorSource)

    stream
      .map(r => (r.id, r.temperature, (random.nextInt().abs % parallelism).toString))
      .flatMap(new myFlatMapFunction)
      .keyBy(_._1)
      .timeWindow(Time.seconds(5))
      .process(new AvgTempFunc)
      .addSink(new RichSinkFunction[(String, String, Double, String)] {
        var  connect: Connection = _
        var ps: PreparedStatement = _
        override def open(parameters: Configuration): Unit = {
          super.open(parameters)
          Class.forName("com.mysql.jdbc.Driver")
          connect = DriverManager.getConnection("jdbc:mysql://localhost:3306?serverTimezone=UTC", "root", "asdfgh")
          ps = connect.prepareStatement("INSERT INTO mytest.myjoinre (id,id_temp,tem, keybyyy) VALUES (?, ?,?,?)")
        }

        override def invoke(value: (String, String, Double, String), context: SinkFunction.Context[_]): Unit = {
          ps.setObject(1,value._1)
          ps.setObject(2,value._2)
          ps.setObject(3,value._3)
          ps.setObject(4,value._4)
          ps.execute()
        }

        override def close(): Unit = {
          super.close()
          if (ps !=  null)
            ps.close()
          if (connect !=  null)
            connect.close()
        }
      })
//      .print()

    env.execute()
  }

  class myFlatMapFunction extends RichFlatMapFunction[(String,Double,String),(String,String,Double,String)] {
    private var map = mutable.HashMap[String,String]()
    override def open(parameters: Configuration): Unit = {
      super.open(parameters)
      import java.sql.DriverManager
      import java.sql.PreparedStatement
      Class.forName("com.mysql.jdbc.Driver")
      val  connect = DriverManager.getConnection("jdbc:mysql://localhost:3306?serverTimezone=UTC", "root", "asdfgh")
      val ps = connect.prepareStatement("select id,value from mytest.myjoin")
      val sets: ResultSet = ps.executeQuery()

      while (sets.next()){
        val id = sets.getString("id")
        val value = sets.getString("value")
        if (id != null){
          map += (id -> value)
        }

      }

    }
    override def flatMap(in: (String,Double,String), collector: Collector[(String, String, Double, String)]): Unit = {
      val mykey =  map.getOrElse(in._3,null)

      collector.collect((in._1,mykey,in._2,in._3))
    }

  }
  class AvgTempFunc extends ProcessWindowFunction[(String, String,Double, String), (String, String,Double, String), String, TimeWindow] {
    override def process(key: String, context: Context, elements: Iterable[(String, String,Double, String)], out: Collector[(String, String,Double, String)]): Unit = {
      //      val size = elements.size
      //      var sum: Double = 0.0
      //      for (r <- elements) {
      //        sum += r._2
      //      }
      //      out.collect((key, sum / size))
      for (r <- elements) {
        out.collect(r)
      }

    }
  }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值