RDD和DataFrame、DateSet关系
DataFrame=RDD-泛型+schema+sql+优化
DataSet=RDD+schema+sql+优化
DataFrame=DataSet[Row]
DataSet=DataFrame.as[Row]
DataFrame劣势
Dataframe的劣势在于在编译期缺少类型安全检查,导致运行时出错。
RDD、DataFrame、DataSet三者之间的转换总结
RDD-》DF、DS:调用toDF、toDS方法
DF、DS-》RDD:调用rdd方法
DF-》DS:DF.as[Row]
DS-》DF:调用toDF方法
SParkSQL查询风格
DSL风格:使用算子进行操作,对编程能力有一定的要求
SQL风格:典型的SQL语句,对数据库管理员和一些会写SQL语句的程序员好用。(注意:在使用SQL风格查询时,必须将数据注册成一张表)
SparkSQL代码程序入口
//创建SparkSQL程序入口
val spark: SparkSession = SparkSession.builder().appName("demo").master("local[*]").getOrCreate()
//SparkSession封装了SParkContext
val sc: SparkContext = spark.sparkContext
//减少日志打印,与程序入口无关
sc.setLogLevel("WARN")
SparkSQL代码(DSL风格和SQL风格)
package bigdata
import org.apache.spark.SparkContext
import org.apache.spark.sql.{DataFrame, SparkSession}
object Demo02 {
def main(args: Array[String]): Unit = {
//创建SparkSQL程序入口
val spark: SparkSession = SparkSession.builder().appName("demo").master("local[*]").getOrCreate()
//SparkSession封装了SParkContext
val sc: SparkContext = spark.sparkContext
//减少日志打印,与程序入口无关
sc.setLogLevel("WARN")
//加载json文件
val personDF: DataFrame = spark.read.json("D:\\test\\data\\people.json")
/* //展示表内容
personDF.show()
//查看schema信息
personDF.printSchema()*/
//使用DSL风格查询年龄大于30岁的数据
//完全体写法
// personDF.select(personDF.col("name"),personDF.col("age")).show()
//导包
import spark.implicits._
//使用DSL风格查询年龄大于30的数据
personDF.filter($"age">30).show()
//使用SQL风格查询年龄大于30 的数据
//使用SQL风格前必须将数据注册成一张表
personDF.createOrReplaceTempView("t_person")
spark.sql("select * from t_person where age >30").show()
}
}
两种风格的使用
DSL风格:使用DF/DS.select()
SQL风格:使用spark.sql()
RDD、DataFrame、DataSet三者之间的转化
//RDD->DataFrame
val df: DataFrame = personRDD.toDF()
//RDD->DataSet
val ds: Dataset[People1] = personRDD.toDS()
//DataFrame->RDD
val rdd: RDD[Row] = df.rdd
//DataSet->RDD
val rdd1: RDD[People1] = ds.rdd
//DataFrame->DataSet
val ds1: Dataset[People1] = df.as[People1]
//DataSet->DataFrame
val df1: DataFrame = ds.toDF()```
SparkSql开窗函数代码
```scala
package demo
import org.apache.spark.SparkContext
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{DataFrame, SparkSession}
/**
* Created by tanjiawang on 2021/7/13.
*/
case class Score(name:String,clas:Int,score:Int)
object Over_Demo {
def main(args: Array[String]): Unit = {
val spark: SparkSession = SparkSession.builder().appName("over").master("local[*]").getOrCreate()
val sc: SparkContext = spark.sparkContext
sc.setLogLevel("WARN")
sc.textFile("")
val arr01 = Array(("a",1,88),
("b",1,78),
("c",1,95),
("d",2,74),
("e",2,92),
("f",3,99),
("g",3,99),
("h",3,45),
("i",3,53),
("j",3,78))
//将数据转换为DataFrame
import spark.implicits._
val rdd: RDD[(String, Int, Int)] = sc.makeRDD(arr01)
val scoreRDD: RDD[Score] = rdd.map(x=>Score(x._1,x._2,x._3))
val scoreDF: DataFrame = scoreRDD.toDF()
scoreDF.show()
//使用sql风格查询,将数据注册成一张表
scoreDF.createOrReplaceTempView("t_score")
/* spark.sql(
"""
|select * from t_score
""".stripMargin).show()*/
//rank():跳跃排序,有两个并列第一名,第三个就直接是第三名,将第二名跳过
/* spark.sql(
"""
|select name,clas,score,rank() over(partition by clas order by score desc) rank from t_score
""".stripMargin).show()
*/
//dense_rank():连续排序,有两个第一名,第三个是第二名,不会跳跃
/*spark.sql(
"""
|select name,clas,score,dense_rank() over(partition by clas order by score desc) rank from t_score
|
""".stripMargin).show()*/
//row_number()连续排序,不会出现并列情况,按照字符顺序排序
/* spark.sql(
"""
|select name,clas,score,row_number() over(partition by clas order by score desc) rank from t_score
""".stripMargin).show()
*/
//讲使用开窗函数后的查询结果作为一张临时表,这个临时表有每个班的成绩排名,再取前三名
spark.sql(
"""
|select * from (select name,clas,score,row_number() over(partition by clas order by score desc) rank from t_score)where rank<=3
""".stripMargin).show()
}
}
spark读取Oracle配置连接
val personDF2: DataFrame = spark.read
.format("jdbc")
.option("url", "jdbc:oracle:thin:@localhost:1521:xe")
.option("driver", "oracle.jdbc.driver.OracleDriver")
.option("user", "system")
.option("password", "oracle")
.option("dbtable", "person")
.load()
personDF2.createOrReplaceTempView("t_dept")
//往oracle加入数据
spark.sql(
"""
|insert into table t_dept values(6,'it部')
""".stripMargin).show()
通过查询到的临时表创建hive并存入
spark.sql("create table tyru as select * from t_yn")
break和continue功能
1、breakable方法写到for循环里面,调用break方法,起到了continue功能;
2、breakable方法写到for循环外面,调用break方法,起到了break功能。
3、return起到了break功能。
import scala.util.control.Breaks._
//continue功能
for(i<-1 to 20){
breakable{
if(i==15){
break()
}
println(i)
}
}
//break功能
breakable {
for (x <- 1 to 20) {
if(x==7){
break()
}
println(x)
}
}
scala函数与方法
方法与函数定义形式不同
方法就是函数,函数也是对象
函数可以作为参数传递到方法中去
方法的定义形式
//def 方法 (参数名:参数类型,参数名:参数类型):返回值类型={方法体}
//def 方法名(参数名:参数类型,参数名:参数类型)={方法体}
函数的
方法和函数的参数个数
最多传22个,最少可以一个不传