Spark SQL 編程初級(jí)實(shí)踐詳解
寫(xiě)在前面
- Linux:
CentOS7.5 - Spark:
spark-3.0.0-bin-hadoop3.2 - IDE:
IntelliJ IDEA2020.2.3
第1題:Spark SQL 基本操作
將下列 JSON 格式數(shù)據(jù)復(fù)制到 Linux 系統(tǒng)中,并保存命名為 employee.json。
{ "id":1 , "name":" Ella" , "age":36 }; { "id":2, "name":"Bob","age":29 }; { "id":3 , "name":"Jack","age":29 }; { "id":4 , "name":"Jim","age":28 } ;{ "id":4 , "name":"Jim","age":28 }; { "id":5 , "name":"Damon" } ;{ "id":5 , "name":"Damon" }
為 employee.json 創(chuàng)建 DataFrame,并寫(xiě)出 Scala 語(yǔ)句完成下列操作:
- 第1小題:查詢(xún)所有數(shù)據(jù);
- 第2小題:查詢(xún)所有數(shù)據(jù),并去除重復(fù)的數(shù)據(jù);
- 第3小題:查詢(xún)所有數(shù)據(jù),打印時(shí)去除 id 字段;
- 第4小題:篩選出 age>30 的記錄;
- 第5小題:將數(shù)據(jù)按 age 分組;
- 第6小題:將數(shù)據(jù)按 name 升序排列;
- 第7小題:取出前 3 行數(shù)據(jù);
- 第8小題:查詢(xún)所有記錄的 name 列,并為其取別名為 username;
- 第9小題:查詢(xún)年齡 age 的平均值;
- 第10小題:查詢(xún)年齡 age 的最小值。
主程序代碼
import org.apache.spark.sql.{DataFrame, SparkSession}
object t1 {
def main(args: Array[String]): Unit = {
val spark: SparkSession = SparkSession.builder()
.appName("t1")
.master("local[2]")
.getOrCreate()
import spark.implicits._
val df: DataFrame = spark.read.json("dataset/ch05/employee.json")
// df.show()
// df.distinct().show()
// df.drop("id").show()
// df.filter(df("age") > 20).show()
// df.groupBy("name").count().show()
// df.sort(df("name").asc).show()
// val rows = df.take(3)
// rows.foreach(println)
// df.select(df("name").as("username")).show()
// df.agg("age" -> "avg").show()
df.agg("age" -> "min").show()
}
}
主程序執(zhí)行結(jié)果
下圖從上到下、從左到右以此為第一、二、三、…、十道題的執(zhí)行結(jié)果

本題很簡(jiǎn)單,就是相關(guān)方法的調(diào)用。
第2題:編程實(shí)現(xiàn)將 RDD 轉(zhuǎn)換為 DataFrame
題目
源文件內(nèi)容如下(包含 id,name,age):
1,Ella,36 2,Bob,29 3,Jack,29
請(qǐng)先將數(shù)據(jù)復(fù)制保存到 Linux 系統(tǒng)中,命名為 employee.txt,實(shí)現(xiàn)從 RDD 轉(zhuǎn)換得到 DataFrame,并按“id:1,name:Ella,age:36”的格式打印出 DataFrame 的所有數(shù)據(jù)。請(qǐng)寫(xiě)出程序代碼。
主程序代碼
import org.apache.spark.sql.{DataFrame, SparkSession}
object t2 {
def main(args: Array[String]): Unit = {
val spark: SparkSession = SparkSession.builder()
.appName("t1")
.master("local[2]")
.getOrCreate()
val employeeInfo = spark.sparkContext.textFile("/input/dataset/employee.txt")
import spark.implicits._
val employeeDF: DataFrame = employeeInfo.map(_.split(","))
.map(attributes =>
Employee(attributes(0).trim.toInt, attributes(1), attributes(2).trim.toInt)
).toDF()
employeeDF.createTempView("employee")
val employeeRDD: DataFrame = spark.sql("select id, name, age from employee")
employeeRDD.map(e => {
"id:" + e(0) + ",name:" + e(1) + ",age:" + e(2)
}).show(10, false)
}
}
case class Employee(id: Long, name: String, age: Long) {
}
主程序執(zhí)行結(jié)果

本題重在map算子的使用并創(chuàng)建視圖執(zhí)行sql查詢(xún),注意程序中要使用到import spark.implicits._,
第3題:編程實(shí)現(xiàn)利用 DataFrame 讀寫(xiě) MySQL 的數(shù)據(jù)
題目
(1)在 MySQL 數(shù)據(jù)庫(kù)中新建數(shù)據(jù)庫(kù) sparktest,再創(chuàng)建表 employee,包含如表 6-2 所示的 兩行數(shù)據(jù)。

(2)配置 Spark 通過(guò) JDBC 連接數(shù)據(jù)庫(kù) MySQL,編程實(shí)現(xiàn)利用 DataFrame 插入如表 6-3 所 示的兩行數(shù)據(jù)到 MySQL 中,最后打印出 age 的最大值和 age 的總和。

主程序代碼
import java.util.Properties
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.types.{IntegerType, StringType, StructField, StructType}
import org.apache.spark.sql.{DataFrame, Row, SparkSession}
object t3 {
def main(args: Array[String]): Unit = {
val spark: SparkSession = SparkSession.builder()
.appName("t3")
.master("local[2]")
.getOrCreate()
val employeeRDD: RDD[Array[String]] = spark.sparkContext.parallelize(
Array("3 Mary F 26", "4 Tom M 23")).map(_.split(" ")
)
val schema: StructType = StructType(List(
StructField("id", IntegerType, true),
StructField("name", StringType, true),
StructField("gender", StringType, true),
StructField("age", IntegerType, true)
))
val rowRDD: RDD[Row] = employeeRDD.map(p => Row(p(0).toInt, p(1).trim, p(2).trim, p(3).toInt))
val df: DataFrame = spark.createDataFrame(rowRDD, schema)
val properties = new Properties()
properties.put("user", "root");
properties.put("password", "123456");
properties.put("driver", "com.mysql.jdbc.Driver");
// serverTimezone=UTC語(yǔ)句需要跟在數(shù)據(jù)庫(kù)連接語(yǔ)句的第一個(gè)位置,否則會(huì)報(bào)錯(cuò)
df.write.mode("append").jdbc("jdbc:mysql://localhost:3306/bd01_spark?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false",
"bd01_spark.employee", properties)
val jdbcDF: DataFrame = spark.read.format("jdbc")
.option("url", "jdbc:mysql://localhost:3306/bd01_spark")
.option("driver", "com.mysql.jdbc.Driver")
.option("dbtable", "employee")
.option("user", "root")
.option("password", "123456")
.load()
jdbcDF.agg("age" -> "max", "age" -> "sum").show(10, false)
}
}
本題主要在于MySQL的JDBC連接創(chuàng)建。
主程序執(zhí)行結(jié)果

以上就是Spark SQL 編程初級(jí)實(shí)踐詳解的詳細(xì)內(nèi)容,更多關(guān)于Spark SQL編程的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java Spring中Quartz調(diào)度器詳解及實(shí)例
這篇文章主要介紹了Java Spring中Quartz調(diào)度器詳解及實(shí)例的相關(guān)資料,需要的朋友可以參考下2017-02-02
Spring AOP實(shí)現(xiàn)Redis緩存數(shù)據(jù)庫(kù)查詢(xún)?cè)创a
這篇文章主要介紹了Spring AOP實(shí)現(xiàn)Redis緩存數(shù)據(jù)庫(kù)查詢(xún)的相關(guān)內(nèi)容,源碼部分還是不錯(cuò)的,需要的朋友可以參考下。2017-09-09
org.slf4j.Logger中info()方法的使用詳解
這篇文章主要介紹了org.slf4j.Logger中info()方法的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
AndroidHttpClient使用Cookie應(yīng)用分析
今天想把一個(gè)用使用了HttpClient的自動(dòng)簽到小程序移植到Android上,還好Android的SDK自帶了HttpClient的包.當(dāng)然也可以繼續(xù)使用DefaultHttpClient,但用為Android定制的AndroidHttpClient自然更好2012-11-11
springboot+spring?data?jpa實(shí)現(xiàn)新增及批量新增方式
這篇文章主要介紹了springboot+spring?data?jpa實(shí)現(xiàn)新增及批量新增方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-11-11

