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》之RDD转换DataFrame的两种方式的比较
最新推荐文章于 2022-08-18 11:08:42 发布