1、RDD转DataFrame
第一种方式:反射
package scala
import org.apache.spark.rdd.RDD
import org.apache.spark.sql.{DataFrame, SparkSession}
//定义一个样例类
case class Person(id:Int,name:String,age:Int,score:Double)
object SparkTest {
def main(args: Array[String]) {
val ss=SparkSession.builder()
.master("local")
.appName("firstSparkSQL")
.getOrCreate()
//使用sparkSQL的时候都要导入隐式转换
import ss.implicits._
val rdd1=ss.sparkContext.textFile("./words") //读取文件
.map(line =>{
var word=line.split(",") //拆分
//给样例类传参
Person(word(0).toInt,word(1).toString,word(2).toInt,word(3).toDouble)
})
//转成df
val df=rdd1.toDF()
/*
show()方法默认显示20行数据,显示100行,则show(100)
df.printSchema() 可打印表的结构信息
*/
df.show()//打印表数据
ss.stop()
}
}
第二种方式:schema自动推导
package scala
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 SparkTest {
def main(args: Array[String]) {
val ss = SparkSession.builder()
.master("local")
.appName("SparkSQLApp")
.getOrCreate()
import ss.implicits._ //sparkSQL都要导入隐式转换
val rdd: RDD[String] = ss.sparkContext.textFile("./datas/tmp")
//创建行式rdd
val rows= rdd.map(one => {
val word = one.split(",")
Row(word(0).toInt,word(1).toString,word(2).toInt,word(3).toInt)
})
val schema=StructType(List(
//指定schema
StructField("id",IntegerType,true),
StructField("name",StringType,true),
StructField("age",IntegerType,true),
StructField("score",IntegerType,true)
))
//创建df
val df: DataFrame = ss.createDataFrame(rows,schema)
df.show()
/*
以下执行SQL
*/
//步骤1:创建临时视图(只能在本session访问)
df.createOrReplaceTempView("t1")
//步骤2:查询并打印结果
ss.sql("select * from t1 where age > 20 ").show()
/*
如果前面注册的视图很多,为了不混乱则可以重新创建一个sparksession
但前面创建的所有临时视图就不能用了,除非用创建全局视图:
frame.createGlobalTempView("t2")
使用时:
spark.sql("select * from global_temp_t2 where age > 20 ").show()
*/
//停止sparksession
ss.stop()
}
}
2、SparkSQL读取json文件
package scala
import org.apache.spark.sql.{DataFrame, Row, SparkSession}
object SparkTest {
def main(args: Array[String]) {
val ss = SparkSession.builder()
.master("local")
.appName("SparkSQLApp")
.getOrCreate()
import ss.implicits._ //sparkSQL都要导入隐式转换
/*
第一种方式:
val df=ss.read.json("./datas/tmp")
*/
//第二种方式
val df=ss.read.format("json").load("./datas/a.txt")
df.show()//打印的时候直接就有了表结构
//停止sparksession
ss.stop()
}
}
3、SparkSQL将json式的RDD/DataSet加载成DataFrame
A、将json式RDD加载成DataFrame
package scala
import org.apache.spark.sql.{SparkSession}
object SparkTest {
def main(args: Array[String]) {
val ss = SparkSession.builder()
.master("local")
.appName("SparkSQLApp")
.getOrCreate()
import ss.implicits._ //sparkSQL都要导入隐式转换
val list=List("{'age':'1','name':'li4'}")
val rdd=ss.sparkContext.makeRDD(list)
val df=ss.read.json(rdd) //rdd加载成df
df.show()
ss.stop()
}
}
B、将DataSet加载成DataFrame
package scala
import org.apache.spark.sql.{SparkSession}
object SparkTest {
def main(args: Array[String]) {
val ss = SparkSession.builder()
.master("local")
.appName("SparkSQLApp")
.getOrCreate()
import ss.implicits._ //sparkSQL都要导入隐式转换
val list=List("{'age':'1','name':'li4'}")
val ds = list.toDS() //list转ds
val df=ss.read.json(ds) //ds加载成df
df.show()
ss.stop()
}
}
4、SparkSQL读取parquet数据
package scala
import org.apache.spark.sql.{DataFrame,SaveMode,SparkSession}
object SparkTest {
def main(args: Array[String]) {
val ss: SparkSession = SparkSession.builder()
.master("local")
.appName("SparkSQLApp")
.getOrCreate()
/*
没有parquet格式的数据,我们利用json造一批
*/
val df0: DataFrame = ss.read.format("json").load("./datas/a.txt")
/*
常用四种savemode:
Append:追加 Overwrite:覆盖 Ignore:忽略 ErrorIfExists:存在即报错
save:也可以保存到hdfs上,如果找不到hdfs在项目中加入hdfs配置文件
*/
df0.write.mode(SaveMode.Overwrite)
.format("parquet")
.save("./datas/b.txt")
/*
第一种方式:
val df=ss.read.format("parquet").load("./datas/b.txt")
*/
//第二种方式
val df: DataFrame = ss.read.parquet("./datas/b.txt")
df.show()
println(df.count)
ss.stop()
}
}
5、SparkSQL读取mysql数据
package scala
import java.util.Properties
import org.apache.spark.sql.{DataFrame, DataFrameReader, SparkSession}
object SparkTest {
def main(args: Array[String]) {
val ss: SparkSession = SparkSession.builder()
.master("local")
.appName("SparkSQLApp")
.config("spark.sql.shuffle.partitions",1)
.getOrCreate()
/*
第一种方式:
val reader: DataFrameReader = ss.read.format("jdbc")
reader.option("url","jdbc:mysql://127.0.0.1:3306/d_student")
reader.option("driver","com.mysql.jdbc.Driver")
reader.option("user","root")
reader.option("password","123456")
reader.option("dbtable","t_student")
val df: DataFrame = reader.load()
df.show()
*/
/*
第二种方式:
val map=Map(
"url" -> "jdbc:mysql://127.0.0.1:3306/d_student",
"driver" -> "com.mysql.jdbc.Driver",
"user" -> "root",
"password" -> "123456",
"dbtable" -> "t_student" //也可以是"(子查询)别名"
)
val df: DataFrame = ss.read.format("jdbc").options(map).load()
*/
//第三种方式
val ps=new Properties()
ps.setProperty("user","root")
ps.setProperty("password","123456")
val df=ss.read.jdbc("jdbc:mysql://127.0.0.1:3306/d_student","t_student",ps)
//单表查询
df.createOrReplaceTempView("t1") //创建临时视图(只能在本session访问)
ss.sql("select * from t1 where age > 20 ").show()
/*
多表查询,涉及到shuffle的操作会开启200个task来处理数据
由spark.sql.shuffle.partitions参数控制,可以人为得调大调小
*/
val df2=ss.read.jdbc("jdbc:mysql://127.0.0.1:3306/d_student","t_grade",ps)
df2.createOrReplaceTempView("t2")
val df3: DataFrame = ss.sql("select * from t1 inner join t2 on t1.sid=t2.stu_id where t2.score>60")
df3.show()
//将结果保存到mysql中
df3.write.mode(SaveMode.Overwrite)
.jdbc("jdbc:mysql://127.0.0.1:3306/d_student","temp",ps)
/*
如果前面注册的视图很多,为了不混乱则可以重新创建一个sparksession
但前面创建的所有临时视图就不能用了,除非之前创建的是全局视图:
frame.createGlobalTempView("t2")
使用时:
spark.sql("select * from global_temp_t2 where age > 20 ").show()
*/
}
}
6、读取hive中的数据
参考:
https://blog.csdn.net/pengzonglu7292/article/details/89682724
1、在spark的conf目录新建一个hive-site.xml,在该配置文件中加入metastore的端口即可,如下
<configuration>
<property>
<name>hive.metastore.uris</name>
<value>thrift://Linux001:9083</value>
</property>
</configuration>
2、启动HDFS & Hive && metastore
3、在main/resources/目录下加入hive-site.xml文件
4、代码
package scala
import org.apache.spark.sql.{SparkSession}
object SparkTest {
def main(args: Array[String]) {
val ss: SparkSession = SparkSession.builder()
.master("local")
.appName("SparkSQLApp")
.enableHiveSupport() //开启hive支持
.getOrCreate()
/*
以下执行hive sql
*/
ss.sql("use default") //使用default数据库
//创建表
ss.sql("create table jizhan_raw(" +
"record_time String, imei String, cell String, ph_num int, " +
"call_num int, drop_num int, duration int,drop_rate int, " +
"net_type String, erl int )" +
"row format delimited fields terminated by ','")
//插入数据
ss.sql("load data local inpath '/opt/apps/data/jizhan.csv' " +
"overwrite into table jizhan_raw")
//查询记录总条数
ss.sql("select count(*) from jizhan_raw ").show()
//创建结果表
ss.sql("create table jizhan_result(imei String,drop_num int,duration int," +
" drop_rate double )row format delimited fields terminated by ','")
//往结果表中插入结果数据
ss.sql("insert into jizhan_result select imei,sum(drop_num) s_drop," +
"sum(duration)s_dura,sum(drop_num)/sum(duration) s_rate from jizhan_raw" +
" group by imei order by s_rate desc limit 10")
//查看结果
ss.sql("select * from jizhan_result").show()
ss.stop()
}
}
4、maven--->clean(清除之前的jar包信息)--->package(打包)------>上传集群----->运行
运行命令:
spark-submit
--master local[*]
--class scala.SparkTest
/opt/apps/spark-2.3.1-bin-hadoop2.6/user_jar/MySpark-1.0-SNAPSHOT-jar-with-dependencies.jar
==================================================================
如果要在idea本地操作hive中的数据:
1、core-site.xml/hdfs-site.xml/hive-site.xml中的文件放到idea的resources源中。
2、数据文件放在idea本地的目录下。
3、代码中数据文件的路径记得更改。
#如果连接虚拟机特别慢
vi /etc/ssh/sshd_config
添加 UseDns no