Spark source API:构建DF、RDD与DF之间的相互转换、show()的三种用法

spark source API:构建DF、RDD与DF之间的相互转换、show()的三种用法

读取csv格式的文件,构建DF
读取json格式的文件,构建DF

1、不需要指定分割方式
2、不需要指定字段名和字段类型(json自带字段和字段类型)
3、 json格式的文件相对于csv,会占用额外的空间,一般不使用json格式存储数据

读取数据库中的数据(JDBC构建DF)

1、不需要指定分割方式
2、不需要指定字段名和字段类型(spark会继承数据库中的表结构)
3、执行之前pom.xml需要有mysql依赖

读取parquet格式的文件,构建DF

1、不需要指定分割方式
2、不需要指定字段名和字段类型
3、parquet是一种压缩的格式,同时会自带列名,可以和hive完全兼容

package com.shujia.sql

import org.apache.spark.sql.{DataFrame, SaveMode, SparkSession}

object Demo2SourceAPI {
  def main(args: Array[String]): Unit = {
    val spark: SparkSession = SparkSession
      .builder()
      .appName("Demo2SourceAPI")
      .master("local")
      .config("spark.sql.shuffle.partitions",1)
      .getOrCreate()
    //导包--导入sql所有的函数
    import org.apache.spark.sql.functions._
    //导入隐式转换
    import spark.implicits._

    /**
     * 读取csv格式的文件,创建DF
     */
    val studentsDF: DataFrame = spark
      .read
      .format("csv")
      .option("sep",",")
      .schema("id STRING, name STRING, age INT, gender STRING, clazz STRING")
      .load("data/students.txt")
//    studentsDF.show()

    /**
     * 读取json格式的文件,创建DF
     * 读取json格式的文件:
     *    1、不需要指定分割方式
     *    2、不需要指定字段名和字段类型(json自带字段和字段类型)
     * json格式的文件相对于csv,会占用额外的空间,一般不使用json格式存储数据
     */
    val jsonDF: DataFrame = spark
      .read
      .format("json")
      .load("data/students.json")
//    jsonDF.printSchema() json格式的文件自带表结构,可以使用printSchema()查看它自带的表结构
//    jsonDF.show()

    /**
     *  使用JDBC构建DF(读取数据库中的数据)
     *  1、不需要指定分割方式
     *  2、不需要指定字段名和字段类型(spark会继承数据库中的表结构)
     *  3、执行之前pom.xml需要有mysql依赖
     */
    val jdbcDF: DataFrame = spark
      .read
      .format("jdbc")
      .option("url","jdbc:mysql://master:3306")
      .option("dbtable", "lyw11.student")
      .option("user", "root")
      .option("password", "123456")
      .load()
    jdbcDF.show()

    /**
     * 读取parquet格式的文件:
     *  1、不需要指定分割方式
     *  2、不需要指定字段名和字段类型
     *
     * parquet是一种压缩的格式,同时会自带列名,可以和hive完全兼容
     *
     */
    //如果我们现在手里没有parquet格式的文件
    //我们可以将csv格式的文件转成parquet格式的文件(利用保存数据来转格式)
    studentsDF
      .write
      .mode(SaveMode.Overwrite) //指定保存模式
      .format("parquet")//指定保存格式为parquet
      .save("data/parquet")//指定路径和输出目录

    //读取parquet格式的文件
    val parquetDF: DataFrame = spark
      .read
      .format("parquet")
      .load("data/parquet")
    parquetDF.show()
  }
}
RDD与DF可以相互转换
RDD转换为DF:.toDF
DF转换成RDD :.rdd
package com.shujia.sql

import org.apache.spark.SparkContext
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{DataFrame, Row, SparkSession}

object Demo3RDDToDF {
  def main(args: Array[String]): Unit = {
    val spark: SparkSession = SparkSession
      .builder()
      .master("local")
      .appName("Demo3RDDToDF")
      .getOrCreate()

    //导入隐式转换
    import spark.implicits._
    //导入所有的函数
    import org.apache.spark.sql.functions._


    //先获取sparkContext,通过SparkContext才能调用textFile
    val sc: SparkContext = spark.sparkContext
    //读取文件构建RDD
    val stdeuntRDD: RDD[String] = sc.textFile("data/students.txt")
    //切分一下数据,转换成元组的形式
    val stuRDD: RDD[(String, String, Int, String, String)] = stdeuntRDD.map(stu => {
      val split: Array[String] = stu.split(",")
      (split(0), split(1), split(2).toInt, split(3), split(4))
    })
    stuRDD.foreach(println)
    //(1500100001,施笑槐,22,女,文科六班)
    //...
      
    /**
     * 将RDD转换成DF  .toDF("列名")
     * RDD的类型是一个元组,转换的时候需要指定列名
     */
    val df: DataFrame = stuRDD.toDF("id", "name", "age", "gender", "clazz")
    df.show()
    //+----------+------+---+------+--------+
    //|        id|  name|age|gender|   clazz|
    //+----------+------+---+------+--------+
    //|1500100001|施笑槐| 22|    女|文科六班|
    //|1500100002|吕金鹏| 24|    男|文科六班|
    //...

    /**
     * DF转换成RDD  .rdd
     * 类型是ROW,ROW代表一行数据,可以使用列名获取列值
     */
    val rdd: RDD[Row] = df.rdd

    /**
     * 解析Row,使用列名获取列值----getAs("列名")
     */
    val tRDD1: RDD[(String, String, Int, String, String)] = rdd.map(row => {
      val id: String = row.getAs[String]("id")
      val name: String = row.getAs[String]("name")
      val age: Int = row.getAs[Int]("age")
      val gender: String = row.getAs[String]("gender")
      val clazz: String = row.getAs[String]("clazz")
      (id, name, age, gender, clazz)
    })
    tRDD1.foreach(println)
    //(1500100001,施笑槐,22,女,文科六班)
    //...

    /**
     * 解析Row,使用模式匹配
     */
    val tRDD2: RDD[(String, String, Int, String, String)] = rdd.map {
      case Row(id: String, name: String, age: Int, gender: String, clazz: String) =>
        (id, name, age, gender, clazz)
    }
    tRDD2.foreach(println)
    //(1500100001,施笑槐,22,女,文科六班)
    //...
    
  }
}
DF中的show()用法
package com.shujia.sql

import org.apache.spark.sql.{DataFrame, SparkSession}

object Demo4Show {
  def main(args: Array[String]): Unit = {
    val spark: SparkSession = SparkSession
      .builder()
      .master("local")
      .appName("Demo4Show")
      .getOrCreate()


    val studentsDF: DataFrame = spark
      .read
      .format("csv")
      .option("sep", ",") //默认分割方式是逗号
      .schema("id STRING, name STRING , age INT ,gender STRING ,clazz STRING")
      .load("data/students.txt")

    /**
     * 指定打印的行数,show()默认打印20行
     */
    //打印数据(默认打印前20行)
    studentsDF.show()

    //打印数据,指定获取的行数
    studentsDF.show(100)

    /**
     * 当单行数据字符较长时,打印的时候会出现省略标点
     * 想要查看完整的数据,需要指定参数
     */
    //完全显示数据
    studentsDF.show(100, false)
  }
}
posted @ 2022-03-12 20:43  阿伟宝座  阅读(967)  评论(0编辑  收藏  举报