Spark(SparkSql) 写数据到 MySQL中(Spark读取TCP socket/文件)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zimiao552147572/article/details/88558261

SparkSql将数据写入到MySQL中:利用sparksql将数据写入到mysql表中(本地运行)
        1.通过IDEA编写SparkSql代码
            package itcast.sql
            import java.util.Properties
            import org.apache.spark.rdd.RDD
            import org.apache.spark.sql.{DataFrame, Dataset, SaveMode, SparkSession}

              // 创建case class样例类Student
              case class Student(id:Int,name:String,age:Int)

            //sparksql写入数据到mysql中
            object SparkSqlToMysql 
            {
                  def main(args: Array[String]): Unit = 
                {
                        // 1、创建sparkSession对象
                    // 本地模式运行:SparkSession.builder().appName("SparkSqlToMysql").master("local[2]").getOrCreate()
                    // 集群模式运行:SparkSession.builder().appName("SparkSqlToMysql").getOrCreate()
                          val spark: SparkSession = SparkSession.builder().appName("SparkSqlToMysql").master("local[2]").getOrCreate()
                    // 通过sparkSession获取sparkContext
                           val sc: SparkContext = spark.sparkContext
                    sc.setLogLevel("WARN")//设置日志输出级别        
                           // 2、通过sparkContext加载数据文件。此处输入读取源是person.txt。
                     val data: RDD[String] = sc.textFile(args(0)) 
                          // 3、切分每一行,每一行中的数据以空格切分,每一行数据便分别封装为每一个String[]数组
                          val arrRDD: RDD[Array[String]] = data.map(_.split(" "))
                          // 4、RDD关联case class样例类Student。map输出为每个Student对象。
                    // x(下标值):获取每一个String[]数组中下标值对应的元素值赋值到每个Student对象中。
                          val studentRDD: RDD[Student] = arrRDD.map(x => Student(x(0).toInt,x(1),x(2).toInt))
                          // 将RDD转换成DataFrame首先需要导入隐式转换
                          import spark.implicits._
                          // 5、将RDD转换成DataFrame:val DataFrame对象: DataFrame = RDD数据.toDF()
                          val studentDF: DataFrame = studentRDD.toDF()
                          // 6、将DataFrame注册成表:DataFrame对象.createOrReplaceTempView("表名")
                          studentDF.createOrReplaceTempView("student")
                    //打印dataframe中的结果数据
                        studentDF.show()
                          // 7、操作student表 ,按照年龄进行降序排列
                          val resultDF: DataFrame = spark.sql("select * from student order by age desc")

                          // 8、把结果保存在mysql表中
                            // 创建Properties对象,配置连接mysql的用户名和密码
                            val prop =new Properties()
                            prop.setProperty("user","root")
                            prop.setProperty("password","admin")
 
                          // 1.把dataframe中数据写出到MySQL数据表中时,可以配置插入mode:overwrite覆盖、append追加、ignore忽略、error默认表存在则报错
                          // 2.mode需要对应4个参数:
                          //    overwrite:覆盖(它会帮你创建一个表,然后进行覆盖)
                          //    append:追加(它会帮你创建一个表,然后把数据追加到表里面)
                          //    ignore:忽略(它表示只要当前表存在,它就不会进行任何操作)
                          //    ErrorIfExists:只要表存在就报错(默认选项)
                    // 3.不配置mode参数时,则默认使用ErrorIfExists(只要表存在就报错)
                    // 4.jdbc("jdbc:mysql://IP或主机名:3306/数据库名","表名",Properties属性)
                    
                          // resultDF.write.mode(SaveMode.Overwrite).jdbc("jdbc:mysql://NODE1:3306/spark","student",prop)
                        resultDF.write.jdbc("jdbc:mysql://NODE1:3306/spark","student",prop)

                          spark.stop()
                    }
            }

===========================================================

package cn.itcast.stream

import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.streaming.{Seconds, StreamingContext}
import org.apache.spark.streaming.dstream.{DStream, ReceiverInputDStream}

import org.apache.spark.SparkContext
import org.apache.spark.rdd.RDD
import java.util.Properties
import org.apache.spark.sql.{DataFrame, Dataset, SaveMode, SparkSession}
 
case class Person(id:Int, name:String, age:Int)

/*
* window:nc.exe -l -p 9999端号
* Linus:nc -lk 9999端号
* */
//todo:利用sparkStreaming接受socket数据,实现单词计数
object SparkStreamingSocket {
  def main(args: Array[String]): Unit = {

//    //第一种获取SparkContext的写法
//    //1、创建sparkConf   设置master的地址local[N] ,n必须大于1,其中1个线程负责去接受数据,另一线程负责处理接受到的数据
//      val sparkConf: SparkConf = new SparkConf().setAppName("SparkStreamingSocket").setMaster("local[2]")
//    // 2、创建sparkContext
//      val sc = new SparkContext(sparkConf)

    //第二种获取SparkContext的写法
    // 1、构建sparkSession 指定appName和master的地址。设置master的地址local[N] ,n必须大于1,其中1个线程负责去接受数据,另一线程负责处理接受到的数据
    val spark: SparkSession = SparkSession.builder().appName("SparkStreamingSocket").master("local[2]").getOrCreate()
    // 2、从sparkSession获取sparkContext对象
    val sc: SparkContext = spark.sparkContext
    
      sc.setLogLevel("WARN") //日志级别为 警告  
    //3、创建streamingContext,需要sparkContext和以多久时间间隔为一个批次
     val ssc = new StreamingContext(sc,Seconds(1))
    //4、通过streaming接受socket数据
      val stream: ReceiverInputDStream[String] = ssc.socketTextStream("NODE1",9999)

    //5、切分每一行。
     //流的扁平化,最终输出的数据类型为一维数组Array[String],被分割符分割出来的每个数据都仅存储到同一个一维数组中。
     //并且还会以回车换行符作为默认的分隔符,即回车换行符前面的数据也会被自动进行分割后,同样存储到同一个一维数组中。
     //val words: DStream[String] = stream.flatMap(_.split(" "))

     //最终输出的数据类型为二维数组Array[Array[String]]。
     //一行数据就为一个一维数组Array[String],多行数据就有多个一维数组,最终多个一维数组一起被封装到同一个一维数组中。
     val words: DStream[Array[String]] = stream.map(_.split(" "))

     //二维数组.foreachRD:对二维数组进行遍历,遍历出每个一维数组,即遍历出每行数据
        words.foreachRDD(rdd=>
        {
          val x: Long = rdd.count() //判断每个一维数组中的元素数量,即获取一行数据中被空格分割出来的多个小字符串的数量
          println(x)
          if (x > 0)   
          { 
            //rdd.map:对每个一维数组进行,即遍历出“每行中被空格切割出来的”多个小字符串,并把一行信息封装为一个RDD[Person]对象
            val personRDD: RDD[Person] = rdd.map(x => Person(x(0).toInt,x(1),x(2).toInt))

            // 将personRDD 转化为 DataFrame,并且需要首先手动导入隐式转换
            import spark.implicits._
            //val DataFrame对象 = RDD数据.toDF() 或 RDD数据.toDF
            val personDF: DataFrame = personRDD.toDF()

            // -------------------DSL语法操作 --------------
            //1、显示DataFrame的数据,默认显示20行。可以指定显示N行:show(N)
            personDF.show()
            //2、显示DataFrame的schema信息(表结构信息)
            personDF.printSchema()
            //3、显示DataFrame记录数
            println(personDF.count())
 
            // --------------------SQL操作风格 -----------
            // 将DataFrame注册成表
            personDF.createOrReplaceTempView("t_person")
            // 传入sql语句,进行操作
            spark.sql("select * from t_person").show()

            val resultDF: DataFrame = spark.sql("select * from t_person")
            val prop =new Properties()
            prop.setProperty("user","root")
            prop.setProperty("password","admin")
 
            resultDF.write.mode(SaveMode.Append).jdbc("jdbc:mysql://NODE1:3306/spark","student",prop)
          }
        })
//    //6、每个单词记为1
//      val wordAndOne: DStream[(String, Int)] = words.map((_,1))
//    //7、相同单词出现的次数累加
//      val result: DStream[(String, Int)] = wordAndOne.reduceByKey(_+_)
//    //8、打印
//      result.print()

    //9、开启流式计算
      ssc.start()
      //一直会阻塞,等待退出
      ssc.awaitTermination()
  }
}

猜你喜欢

转载自blog.csdn.net/zimiao552147572/article/details/88558261
今日推荐