spark sql idea常规操作

该博客介绍了Spark SQL的使用,包括Maven依赖、数据读写、转换操作及UDF与UDAF函数。示例代码展示了如何创建SparkSession,读取CSV文件,注册UDF函数,以及进行RDD、DataFrame和DataSet之间的转换。此外,还涵盖了数据的读取和写入,如Parquet、ORC格式以及从MySQL数据库的读写操作。
摘要由CSDN通过智能技术生成

maven依赖

<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-sql_2.11</artifactId>
    <version>2.4.5</version>
</dependency>

 1、常规准备

1)写代码创建环境

2)导入隐式转换

3)需要使用到 sql的需要先创建视图

4)读取csv格式的文件需要指定列头

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

object SparkSqlTest1 {
  def main(args: Array[String]): Unit = {
    /**
     * 可以通过sparkconf来创建sparksession对象,也可以直接创建
     * val sparkConf: SparkConf = new SparkConf().setMaster("local[*]").setAppName("SparkSQL")
     *
     * val sparkSession = SparkSession.builder().config(sparkConf).getOrCreate()
     */

    val spark: SparkSession = SparkSession .builder()
      //这个mater是在本地测试的时候要加上的,在集群上运行需要删除,
      .master("local[*]")
      .appName("SparkSqlTest1")
      .getOrCreate()

    //读取csv格式的数据我们需要自己添加表头
    val stuDF: DataFrame = spark
      .read
      .schema("id Int,name String,age Int,gender String,clazz String")
      .csv("data/students.txt")


    //添加视图,可以在sql中使用
    stuDF.createOrReplaceTempView("stu_view")
    spark.sql("select * from stu_view").show()
    spark.sql("select name,age from stu_view").show()
    spark.sql("select avg(age) from stu_view").show()

    stuDF.select("age","name").show()

    /**
     * 下面这里涉及到了转换操作,需要导入隐式转换
     * 使用隐式转换
     */
    import spark.implicits._

    stuDF.select($"age+1",$"name").show()
    
    stuDF.show()

    spark.close()

  }
}

 2、RDD DataFrame DataSet三者转换

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

object TransformTest {
  def main(args: Array[String]): Unit = {

    val spark = SparkSession
      .builder()
      .master("local[*]")
      .appName("TransformTest")
      .getOrCreate()

    import spark.implicits._
    

    /**
     * RDD -> DataFrame
     * 相比RDD,DataFrame多了结构
     */

    val rdd: RDD[(Int, String, Int)] = spark.sparkContext.makeRDD(List((1, "zhangsan", 30), (2, "lisi", 40)))

    val df: DataFrame = rdd.toDF("id", "name", "age")

    val rowRDD: RDD[Row] = df.rdd

    /**
     * RDD <=> DataSet
     */
    val newDS: Dataset[User] = df.as[User]

    val newDF: DataFrame = newDS.toDF()

    val DS2: Dataset[User] = rdd.map {
      case (id, name, age) => {
        User(id, name, age)
      }
    }.toDS()

    val rdd2 = DS2.rdd
    
    //关闭连接
    spark.close()

  }
}
case class User(id:Int,name:String,age:Int)

3、UDF函数

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

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

    import spark.implicits._

    val stuDF: DataFrame = spark
      .read
      .schema("id Int,name String,age Int,gender String,clazz String")
      .csv("data/students.txt")

    val stu = stuDF.createOrReplaceTempView("stu")

    /**
     * 注册udf函数,传入函数名,函数方法,一进一出
     */
    spark.udf.register("prefixName",(name:String)=>{
      "$name$: "+name
    })

    spark.sql("select prefixName(name) from stu").show()

    spark.close()
  }
}

UDAF

import org.apache.spark.sql.expressions.{MutableAggregationBuffer, UserDefinedAggregateFunction}
import org.apache.spark.sql.types.{DataType, LongType, StructField, StructType}
import org.apache.spark.sql.{DataFrame, Row, SparkSession}

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

    val stuDF: DataFrame = spark
      .read
      .schema("id Int,name String,age Int,gender String,clazz String")
      .csv("data/students.txt")

    val stu = stuDF.createOrReplaceTempView("stu")

    /**
     * 自定义UDAF函数需要继承UserDefinedAggregateFunction类
     */
    spark.udf.register("avg_age",new myAvgUDAF())

    spark.sql("select avg_age(age) from stu").show()



    spark.close()
  }

  /**
   * 自定义聚合函数类,计算平均年龄
   */
  class myAvgUDAF extends UserDefinedAggregateFunction{
    //输入结构
    override def inputSchema: StructType = {
      StructType(
        Array(
          StructField( "age",LongType))
    )
    }

    //缓冲区数据的结构
    override def bufferSchema: StructType = {
      StructType(
        Array(
          StructField( "age",LongType),
          StructField( "count",LongType)

        )
      )
    }

    //函数计算的结果
    override def dataType: DataType = LongType

    //函数的稳定性
    override def deterministic: Boolean = true

    //初始化缓冲区的配置
    override def initialize(buffer: MutableAggregationBuffer): Unit = {
      buffer.update(0,0L)
      buffer.update(1,0L)

    }

    //来一条数据就更新缓冲区
    override def update(buffer: MutableAggregationBuffer, input: Row): Unit = {
      //缓冲区第一个是传入数据的值,第二个是count计数
      buffer.update(0,buffer.getLong(0)+input.getLong(0))
      buffer.update(1,buffer.getLong(1)+1)
    }

    //缓冲区数据合并
    override def merge(buffer1: MutableAggregationBuffer, buffer2: Row): Unit = {
      buffer1.update(0,buffer1.getLong(0)+buffer2.getLong(0))
      buffer1.update(1,buffer1.getLong(1)+buffer2.getLong(1))
    }
    
    //定义输出结果的计算模式
    override def evaluate(buffer: Row): Any = {
      buffer.getLong(0)/buffer.getLong(1)
    }
  }
}

4、读取数据和写数据

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

object Demo2SourceAPI {
  def main(args: Array[String]): Unit = {


    val spark = SparkSession 
      .builder()
      .appName("Demo2SourceAPI")
      .master("local")
      .getOrCreate()

    spark.read
      .schema("id Int,name String,age Int,gender String,clazz String")
      //我们可以通过这个方法设置分割符号,有的文件如果不是逗号分割就使用这个方法
      .option("sep","|")
      .csv("spark/data.txt/student.txt")

    /**
     * 我们还可以指定某种格式读取数据
     * 这里就读取一下json格式的数据
     * 但是json里面一条数据就记录了一次列名,非常浪费空间
     */
    val stuDF: DataFrame = spark
      .read
      .format("json")
      .load("spark/data.txt/students.json")

    stuDF.show(100)

     /**
     * 生成parquet文件
     */
    stuDF
      .write
      .mode(SaveMode.Overwrite)
      //指定输出格式指定写入的模式:
      // Append追加、Overwrite覆盖、ErrorIfExists存在就报错、Ignore存在即忽略
      .format("parquet")
      //指定输出路径
      .save("spark/data/parquet")

    /**
     * 写一个orc格式的文件
     * orc格式是一个列式存储,有压缩的
     * 从文件名我们可以看出来,这是通过snappy压缩的
     */
    stuDF
      .write
      .mode(SaveMode.Overwrite)
      //指定输出格式指定写入的模式:
      // Append追加、Overwrite覆盖、ErrorIfExists存在就报错、Ignore存在即忽略
      .format("orc")
      //指定输出路径
      .save("spark/data/orc")

    /**
     * 读取parquet文件,自带snappy,对数据进行压缩
     */
    val parDF: DataFrame = spark
      .read
      .format("parquet")
      .load("spark/data/parquet")

    parDF.show(100)



    /**
     * 读取orc文件
     */
    val orcDF: DataFrame = spark
      .read
      .format("orc")
      .load("spark/data/orc")

    orcDF.show(10)

    /**
     * 读取mysql的数据
     */
    val jdbcDF: DataFrame = spark.read
      .format("jdbc")
      .option("url", "jdbc:mysql://doker:3306/student")
      .option("driver","com.mysql.jdbc.Driver")
      .option("dbtable", "student")
      .option("user", "root")
      .option("password", "123456")
      .load()

    jdbcDF.show()
    
    stuDF.write
      .format("jdbc")
      .option("url", "jdbc:mysql://doker:3306/student")
      .option("driver","com.mysql.jdbc.Driver")
      .option("dbtable", "student1")
      .option("user", "root")
      .option("password", "123456")
      .mode(SaveMode.Append)
      .save()
    
    spark.close()

  }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值