《深入理解Spark》之RDD转换DataFrame的两种方式的比较

package com.lyzx.day19

import org.apache.spark.sql.types.{StringType, StructField, StructType}
import org.apache.spark.{SparkConf, SparkContext}
import org.apache.spark.sql.SQLContext
import org.apache.spark.sql.Row

class T1 {
  def f1(sc:SparkContext): Unit ={
    val sqlCtx = new SQLContext(sc)
    import  sqlCtx.implicits._

    val myDf = sc.textFile("./Person.txt")
                 .map(x=>x.split(","))
                 .map(x=>My(x(0),x(1),x(2).toInt)).toDF()

    myDf.registerTempTable("myUser")

    val result = sqlCtx.sql("select * from myUser where id >= 2")
    result
      //这儿的_(x)指的是当前一条记录的第(x+1)个属性
      //也就是说要取某一条记录的某个属性可以通过下标的形式(_(index))也可以通过列名的形式(_.getAs[T](colNameStr))
//        .map(_(0))
      .map(_.getAs[String]("name"))
      .foreach(println)
  }


  def f2(sc:SparkContext): Unit ={
    val sqlCtx = new SQLContext(sc)
    val rdd= sc.textFile("./person.txt")
              .map(_.split(","))
              .map(x=>Row(x(0),x(1),x(2)))

    //这儿有局限因为传入的是一个数组,即每一个元素都一样,如果是每个列的
    val schema = StructType(Array(StructField("id",StringType,true),StructField("name",StringType,true),StructField("age",StringType,true)))
    val df = sqlCtx.createDataFrame(rdd,schema)
    df.registerTempTable("person")

    sqlCtx.sql("select name from person where id >=2")
          .foreach(println)

  }

  /**
   * 总结对于两种RDD转DataFrame的方式
   * 结果都是一样,唯一的不同就是定义schema的方式,
   *  反射的方式  Schema是写死的即实体类
   *    优点:使用简单
   *    缺点:如果要修改schema就要是修改实体类即修改麻烦
   *  动态的方式
   *    优点:灵活一些,不过对于列的类型也不够灵活,可以动态的指定列的名称
   *    缺点:使用时麻烦一些
   */
}

//这个类要放在外面而且前面还要加case
//这是因为将一行数据数据转换为My对象后需要序列化
case class My(id:String,name:String,age:Int)
object T1{
  def main(args: Array[String]) {
    val conf = new SparkConf().setAppName("day18").setMaster("local")
    val sc = new SparkContext(conf)

    val t = new T1
    t.f1(sc)
    sc.stop()
  }
}

你可能感兴趣的:(Spark)